/* PINIT Look & Feel theme layer — tokens and component rules per
   PINIT_Styleguide_Erweiterung.docx. Scoped to .pinit-theme so it never
   collides with anything else; PUBLISH's Studio applies this class on
   <body>, the public share viewer deliberately does not (the plan
   principle: "the viewer should interfere as little as possible" with a
   customer's own document design). */

:root, .pinit-theme {
  --pinit-color-brand-dark: #1F1733;
  --pinit-color-primary: #E26A61;
  --pinit-color-primary-hover: #D95D54;
  --pinit-color-primary-soft: rgba(226, 106, 97, 0.12);
  --pinit-color-app-bg: #E5E4DF;
  --pinit-color-surface: #FFFFFF;
  --pinit-color-surface-muted: #F7F5F2;
  --pinit-color-text: #3A362F;
  --pinit-color-text-muted: #6F6F6F;
  --pinit-color-border: #D8D6CF;
  --pinit-color-border-light: #ECE9E2;
  --pinit-color-success: #4DAA57;
  --pinit-color-warning: #F2A93B;
  --pinit-color-error: #D84343;
  --pinit-color-disabled: #BDBDBD;

  /* Readable counterparts of the four colours above. Each is its own
     colour darkened until it clears 4.5:1 against its own 12% tint --
     the darkest surface it appears on, so it also clears white and the
     muted surface. Scaling all three channels by one factor keeps the
     hue, so these are still recognisably the brand and the status
     colours; they are generated by
     apps/shared/services/color.py:text_variant() and pinned by
     apps/shared/tests/test_theme_contrast.py.

     Contrast is symmetric, so each doubles as a safe FILL behind white
     text -- which is why the primary button uses -text as a background.

     --pinit-color-primary-text is overridden per brand at render time
     (apps/brands/services/appearance.py); the status three are not
     brand colours and stay fixed. */
  --pinit-color-primary-text: #AC514A;   /* 5.21:1 on white */
  --pinit-color-success-text: #377A3F;   /* 5.23:1 */
  --pinit-color-warning-text: #916523;   /* 5.13:1 -- replaces a hand-found #92660c */
  --pinit-color-error-text:   #BE3B3B;   /* 5.41:1 */

  --pinit-radius-sm: 6px;
  --pinit-radius-md: 8px;
  --pinit-radius-lg: 14px;
  --pinit-radius-xl: 18px;

  --pinit-shadow-card: 0 8px 18px rgba(0, 0, 0, 0.12);
  --pinit-shadow-card-hover: 0 10px 22px rgba(0, 0, 0, 0.16);

  --pinit-space-1: 4px;
  --pinit-space-2: 8px;
  --pinit-space-3: 12px;
  --pinit-space-4: 16px;
  --pinit-space-6: 24px;
  --pinit-space-8: 32px;

  /* The content column. Was 1040px, which left 400px of empty
     background on a 1440px window while document titles wrapped onto
     three lines -- measured, not guessed. Declared once here because
     the same number also governs the page-level message strip, and two
     literals drift apart. */
  --pinit-content-max: 1440px;

  /* Libre Franklin is PINIT's own face per its CD onepager; Roboto
     was a stand-in. --pinit-font-heading lets a brand pair a second
     face for titles (DIFFRNT does) and otherwise simply inherits. */
  font-family: "Libre Franklin", Arial, sans-serif;
  --pinit-font-heading: inherit;
}

.pinit-theme {
  background: var(--pinit-color-app-bg);
  color: var(--pinit-color-text);
  margin: 0;
  min-height: 100vh;
  font-size: 14px;
  line-height: 20px;
  font-weight: 400;
}

.pinit-theme * { box-sizing: border-box; }

.pinit-theme a { color: var(--pinit-color-primary-text); text-decoration: none; }
.pinit-theme a:hover { text-decoration: underline; }

/* Typography scale */
.pinit-theme h1 { font-family: var(--pinit-font-heading); font-size: 20px; font-weight: 500; line-height: 28px; margin: 0 0 var(--pinit-space-4); }
.pinit-theme h2 { font-family: var(--pinit-font-heading); font-size: 16px; font-weight: 500; line-height: 24px; margin: var(--pinit-space-6) 0 var(--pinit-space-3); }
.pinit-theme label, .pinit-theme .field-label { font-size: 12px; font-weight: 400; line-height: 16px; color: var(--pinit-color-text-muted); display: block; margin-bottom: var(--pinit-space-1); }
.pinit-theme .meta { font-size: 12px; line-height: 16px; color: var(--pinit-color-text-muted); }

/* App shell */
.pinit-shell {
  min-height: 100vh;
}
.pinit-topbar {
  display: flex;
  align-items: center;
  gap: var(--pinit-space-4);
  padding: var(--pinit-space-3) var(--pinit-space-6);
  background: var(--pinit-color-surface);
  border-bottom: 1px solid var(--pinit-color-border-light);
}
.pinit-brand {
  display: flex;
  align-items: center;
  gap: var(--pinit-space-2);
}
.pinit-brand-badge {
  width: 32px;
  height: 32px;
  border-radius: var(--pinit-radius-md);
  background: var(--pinit-color-brand-dark);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.pinit-brand-badge img { width: 18px; height: 18px; }
.pinit-brand-name { font-size: 16px; font-weight: 500; color: var(--pinit-color-text); }

.pinit-nav { display: flex; gap: var(--pinit-space-1); margin-left: var(--pinit-space-6); }
.pinit-nav a {
  display: flex;
  align-items: center;
  gap: var(--pinit-space-1);
  padding: var(--pinit-space-2) var(--pinit-space-3);
  border-radius: var(--pinit-radius-md);
  color: var(--pinit-color-text-muted);
  font-weight: 500;
  font-size: 13px;
}
.pinit-nav a:hover { background: var(--pinit-color-surface-muted); text-decoration: none; }
.pinit-nav a.active { color: var(--pinit-color-primary-text); background: var(--pinit-color-primary-soft); }
.pinit-nav .material-symbols-outlined { font-size: 20px; }

.pinit-icon-sm { font-size: 16px; }
.pinit-icon-md { font-size: 18px; }

/* Visually hidden but still announced. */
.pinit-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;
}

/* First focusable element on every Studio page, so a keyboard user can
   pass the six header stops in one key press. */
.pinit-skip-link {
  position: absolute;
  left: var(--pinit-space-3);
  top: -60px;
  z-index: 10;
  background: var(--pinit-color-surface);
  color: var(--pinit-color-text);
  border: 1px solid var(--pinit-color-border);
  border-radius: var(--pinit-radius-md);
  padding: var(--pinit-space-2) var(--pinit-space-4);
  font-size: 13px;
  transition: top 0.1s ease-in;
}
.pinit-skip-link:focus { top: var(--pinit-space-3); }
.pinit-main:focus { outline: none; }

.pinit-topbar-spacer { flex: 1; }
.pinit-user { font-size: 13px; color: var(--pinit-color-text-muted); display: flex; align-items: center; gap: var(--pinit-space-3); }

.pinit-main {
  max-width: var(--pinit-content-max);
  margin: 0 auto;
  padding: var(--pinit-space-6);
}

/* Cards */
.pinit-card {
  background: var(--pinit-color-surface);
  border: 1px solid var(--pinit-color-border-light);
  border-radius: var(--pinit-radius-lg);
  box-shadow: var(--pinit-shadow-card);
  padding: var(--pinit-space-6);
  margin-bottom: var(--pinit-space-4);
}

/* Buttons — <button> gets the primary look by default (bare element
   selector); <a class="pinit-btn ..."> opts in explicitly. Every rule
   here that needs to win over `.pinit-theme a`'s (class+element,
   specificity 0-1-1) default link color is qualified as
   `.pinit-theme .pinit-btn...` (class+class, 0-2-0, which beats it on
   class count regardless of source order) rather than a bare
   `.pinit-btn...` class alone. */
.pinit-theme button,
.pinit-theme .pinit-btn {
  height: 40px;
  padding: 0 var(--pinit-space-4);
  border-radius: var(--pinit-radius-md);
  font-size: 13px;
  font-weight: 500;
  line-height: 18px;
  border: 1px solid transparent;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: var(--pinit-space-1);
  font-family: inherit;
  text-decoration: none;
}
.pinit-theme button,
.pinit-theme .pinit-btn-primary {
  /* -text, not -primary: white on the raw coral is 3.25:1. Contrast is
     symmetric, so the value derived for "readable as text" is equally
     the one that makes a white label readable on top of it. */
  background: var(--pinit-color-primary-text);
  color: #fff;
}
.pinit-theme button:hover,
.pinit-theme .pinit-btn-primary:hover { background: var(--pinit-color-primary-hover); text-decoration: none; }

.pinit-theme button.pinit-btn-secondary,
.pinit-theme .pinit-btn-secondary {
  background: var(--pinit-color-surface);
  color: var(--pinit-color-text);
  border-color: var(--pinit-color-border);
}
.pinit-theme button.pinit-btn-secondary:hover,
.pinit-theme .pinit-btn-secondary:hover { background: var(--pinit-color-surface-muted); text-decoration: none; }
.pinit-theme button.pinit-btn-danger,
.pinit-theme .pinit-btn-danger { background: var(--pinit-color-error-text); color: #fff; }
.pinit-theme button.pinit-btn-sm,
.pinit-theme .pinit-btn-sm { height: 32px; padding: 0 var(--pinit-space-3); font-size: 12px; }

/* Inputs
   Jede Eingabeart, die ein Formular hervorbringt, steht in dieser Liste.
   Django macht aus einem URLField ein type="url" und aus einem
   IntegerField ein type="number"; fehlt die Art hier, bleibt das Feld ein
   unbehandeltes Browser-Feld -- 153 x 21 px mit dickem grauem Rand neben
   lauter 42 px hohen Feldern. So sahen "Website" (Kunde) und "Höchstzahl
   Aufrufe" (Freigabe) aus, und im Quelltext war nichts zu sehen.
   apps/shared/tests/test_form_controls.py liest alle Formulare der App und
   schlägt an, sobald eine neue Art fehlt. */
.pinit-theme input[type="text"],
.pinit-theme input[type="password"],
.pinit-theme input[type="email"],
.pinit-theme input[type="url"],
.pinit-theme input[type="number"],
.pinit-theme input[type="tel"],
.pinit-theme input[type="search"],
.pinit-theme input[type="date"],
.pinit-theme input[type="datetime-local"],
.pinit-theme input[type="time"],
.pinit-theme input[type="file"],
.pinit-theme select,
.pinit-theme textarea {
  height: 42px;
  padding: 0 var(--pinit-space-3);
  border: 1px solid var(--pinit-color-border);
  border-radius: var(--pinit-radius-sm);
  font-size: 14px;
  font-family: inherit;
  color: var(--pinit-color-text);
  background: var(--pinit-color-surface);
  width: 100%;
  max-width: 480px;
}
.pinit-theme textarea { height: auto; min-height: 160px; padding: var(--pinit-space-3); font-family: "Roboto Mono", monospace; font-size: 13px; }
/* Scoped to the same element list as the sizing rule above. The old
   selector was a bare `input:focus`, so `outline: none` also stripped
   the focus ring from checkboxes, radios and submit inputs -- controls
   this rule was never written for, and which get no replacement from a
   border-colour change. Selecting rows for a bulk archive by keyboard
   was invisible. */
.pinit-theme input[type="text"]:focus,
.pinit-theme input[type="password"]:focus,
.pinit-theme input[type="email"]:focus,
.pinit-theme input[type="url"]:focus,
.pinit-theme input[type="number"]:focus,
.pinit-theme input[type="tel"]:focus,
.pinit-theme input[type="search"]:focus,
.pinit-theme input[type="date"]:focus,
.pinit-theme input[type="datetime-local"]:focus,
.pinit-theme input[type="time"]:focus,
.pinit-theme input[type="file"]:focus,
.pinit-theme select:focus,
.pinit-theme textarea:focus {
  border-color: var(--pinit-color-primary-text);
  box-shadow: 0 0 0 3px var(--pinit-color-primary-soft);
  outline: none;
}

/* Hinweise und Fehler in Formularen.
   Django liefert den Hinweis als <span class="helptext"> und Fehler als
   <ul class="errorlist">; beides hatte keine Regel. Ein Hinweis las sich
   deshalb wie Fliesstext direkt neben dem Feld, ein Fehler wie eine
   schwarze Aufzählung, die man für einen Hinweis halten konnte.
   Fehler in der lesbaren Fehlerfarbe (nie die rohe, siehe
   test_theme_contrast.py) und mit Symbol: Farbe allein trägt keine
   Aussage. Das Symbol kommt aus derselben Schrift wie alle anderen. */
.pinit-theme .helptext {
  display: block;
  margin-top: var(--pinit-space-1);
  font-size: 13px;
  line-height: 18px;
  color: var(--pinit-color-text-muted);
}
.pinit-theme .errorlist {
  list-style: none;
  margin: 0 0 var(--pinit-space-2);
  padding: 0;
  font-size: 13px;
  font-weight: 500;
  line-height: 18px;
  color: var(--pinit-color-error-text);
}
.pinit-theme .errorlist li {
  display: flex;
  align-items: flex-start;
  gap: var(--pinit-space-1);
}
.pinit-theme .errorlist li::before {
  content: "error";
  flex: none;
  font-family: "Material Symbols Outlined";
  font-size: 16px;
  font-weight: 400;
  line-height: 18px;
  letter-spacing: normal;
  text-transform: none;
  white-space: nowrap;
  font-feature-settings: "liga";
}
/* Django setzt aria-invalid="true" selbst an jedes Feld mit Fehler.
   Mit dem Elementnamen davor, und das ist kein Zierrat: ein nacktes
   .pinit-theme [aria-invalid="true"] hat die Spezifität 0-2-0 und verliert
   gegen die Grössenregel oben (.pinit-theme input[type="number"], 0-2-1),
   der Rand blieb grau, obwohl das Attribut gesetzt war. Dieselbe Falle wie
   bei den Knöpfen -- im Browser gefunden, nicht im Quelltext. */
.pinit-theme input[aria-invalid="true"],
.pinit-theme select[aria-invalid="true"],
.pinit-theme textarea[aria-invalid="true"] { border-color: var(--pinit-color-error-text); }
.pinit-theme input[aria-invalid="true"]:focus,
.pinit-theme select[aria-invalid="true"]:focus,
.pinit-theme textarea[aria-invalid="true"]:focus {
  border-color: var(--pinit-color-error-text);
  box-shadow: 0 0 0 3px rgba(216, 67, 67, 0.15);
}

/* Everything else keeps a real, visible ring. :focus-visible so a mouse
   click doesn't leave one behind, which is why the UA default was worth
   replacing rather than merely restoring. */
.pinit-theme a:focus-visible,
.pinit-theme button:focus-visible,
.pinit-theme summary:focus-visible,
.pinit-theme input[type="checkbox"]:focus-visible,
.pinit-theme input[type="radio"]:focus-visible,
.pinit-theme [tabindex]:focus-visible {
  outline: 2px solid var(--pinit-color-primary-text);
  outline-offset: 2px;
  border-radius: var(--pinit-radius-sm);
}
.pinit-theme form p { margin: 0 0 var(--pinit-space-4); }

/* Dashboard stat strip -- flex-wrap + a flex-basis is enough on its own
   to reflow from 4-across to 2x2 (or a single column) on a narrow
   viewport, no media query needed. Found overflowing at 375px width
   during an MVP audit; confirmed by screenshot, not assumed. */
.pinit-dashboard-strip {
  display: flex;
  flex-wrap: wrap;
  gap: var(--pinit-space-4);
  margin-bottom: var(--pinit-space-4);
}
.pinit-dashboard-strip > * { flex: 1 1 140px; }

/* Die vier Kennzahlen über der Dokumentliste sind Verweise in die Liste,
   gefiltert auf genau das, was die Zahl zählt. Als Karte mit Text bleiben
   sie, was sie waren: ohne diese Regeln färbte `.pinit-theme a` jeden Text
   im Verweis in die Linkfarbe und unterstrich ihn beim Daraufzeigen.
   Wie bei den Knopfvarianten (siehe oben) mit dem Elementnamen davor, damit
   die Regel gegen die Linkfarbe gewinnt. */
.pinit-theme a.pinit-stat {
  display: block;
  text-align: center;
  padding: var(--pinit-space-4);
  color: inherit;
}
.pinit-theme a.pinit-stat:hover { text-decoration: none; box-shadow: var(--pinit-shadow-card-hover); }
.pinit-stat-number { display: block; font-size: 24px; font-weight: 500; }
/* Die lesbare Fassung der Farben: die rohe Erfolgsfarbe erreicht auf Weiss
   nicht einmal die 3:1, die für Text dieser Grösse gelten
   (siehe test_theme_contrast.py). */
.pinit-stat-number-success { color: var(--pinit-color-success-text); }
.pinit-stat-number-warning { color: var(--pinit-color-warning-text); }
.pinit-stat-number-muted { color: var(--pinit-color-text-muted); }

/* Wraps a <table> so it scrolls horizontally within its own bounds
   rather than overflowing the page -- the page body itself must never
   scroll sideways. Pair with a .pinit-card that keeps `overflow:hidden`
   for its rounded corners; this inner wrapper is what actually scrolls. */
.pinit-table-scroll { overflow-x: auto; }

/* Die Leiste der Sammelaktionen unter der Dokumentliste. Sie klebt am
   unteren Bildschirmrand, solange die Liste weiter reicht, und ist ohne
   Auswahl gar nicht da: pinit-bulk-bar.js setzt `hidden`. Ohne Skript
   bleibt sie sichtbar und ist eine gewöhnliche Zeile unter der Liste.
   Mit `.pinit-theme` davor, wie jede Regel hier -- und für `hidden` ist
   das Pflicht: das Attribut hat nur die Stärke des Browsers und verliert
   gegen jedes `display`, das wir selbst setzen. */
.pinit-theme .pinit-bulk-bar {
  position: sticky;
  bottom: var(--pinit-space-4);
  z-index: 10;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--pinit-space-3);
  margin-top: var(--pinit-space-4);
  padding: var(--pinit-space-3) var(--pinit-space-4);
  background: var(--pinit-color-surface);
  border: 1px solid var(--pinit-color-border);
  border-radius: var(--pinit-radius-md);
  box-shadow: var(--pinit-shadow-card-hover);
}
.pinit-theme .pinit-bulk-bar[hidden] { display: none; }
.pinit-theme .pinit-bulk-count { font-weight: 500; }

/* Tables / list items */
.pinit-theme table { width: 100%; border-collapse: collapse; }
.pinit-theme thead th {
  background: var(--pinit-color-surface-muted);
  font-weight: 500;
  font-size: 12px;
  color: var(--pinit-color-text-muted);
  text-align: left;
  padding: var(--pinit-space-3) var(--pinit-space-4);
  border-bottom: 1px solid var(--pinit-color-border-light);
}
.pinit-theme tbody td {
  padding: var(--pinit-space-3) var(--pinit-space-4);
  border-bottom: 1px solid var(--pinit-color-border-light);
  font-size: 14px;
}
.pinit-theme input[type="checkbox"] { width: 20px; height: 20px; margin: 0; accent-color: var(--pinit-color-primary-text); }
/* Column behaviour in the data tables. Without this, auto table
   layout gives every column a share of the extra width and the title --
   the only cell anyone reads first -- keeps wrapping while a date
   column sits half empty. Dates, badges and actions take exactly what
   they need; the title gets the rest. */
.pinit-theme td.pinit-col-nowrap,
.pinit-theme th.pinit-col-nowrap { white-space: nowrap; width: 1%; }
.pinit-theme .pinit-col-title { width: 99%; }
/* The customer column deliberately still wraps -- a long company name
   must not be the thing that forces the table sideways. But width: 99%
   on the title left it the table's minimum, 97px, so "Demo DIFFRNT AG"
   broke across three lines next to a 458px title column. A floor, not
   a fixed width: it still gives way on a narrow screen. */
.pinit-theme .pinit-col-customer { min-width: 19ch; }
/* Row actions stay on one line. They were two short English words and
   are now two long German ones -- "Bearbeiten · Verwaltung" wrapped
   where "Edit · Admin" never had to. */
.pinit-theme td.pinit-col-actions { white-space: nowrap; }
.pinit-theme .pinit-badge { white-space: nowrap; }
/* Das Etikett „Neuere Fassung nicht veröffentlicht" ist länger als jedes
   andere und darf umbrechen. Als einzeilige Kapsel machte es die
   Statusspalte 253 px breit und schob die Tabelle über den Rand der
   Karte (gemessen bei 1280 px); umgebrochen ist die Spalte so breit wie
   mit dem alten Etikett „Geändert". Der Radius ist kleiner, weil eine
   mehrzeilige Kapsel mit 999px zu einer Ellipse wird. */
.pinit-theme .pinit-badge.pinit-badge-wrap { white-space: normal; line-height: 1.25; border-radius: 12px; }

.pinit-theme tbody tr:hover { background: var(--pinit-color-surface-muted); }

/* Status badges */
.pinit-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  font-weight: 500;
  padding: 2px 10px;
  border-radius: 999px;
}
.pinit-badge-success { background: rgba(77, 170, 87, 0.14); color: var(--pinit-color-success-text); }
.pinit-badge-warning { background: rgba(242, 169, 59, 0.16); color: var(--pinit-color-warning-text); }
.pinit-badge-muted { background: var(--pinit-color-surface-muted); color: var(--pinit-color-text-muted); }
.pinit-badge-error { background: rgba(216, 67, 67, 0.12); color: var(--pinit-color-error-text); }

/* --- Die Dokumentliste auf schmalen Fenstern (story-043) -------------
   Bei 375 px war die Tabelle 1337 px breit in einem 341 px breiten
   Fenster, und die erste Dokumentzeile begann 1670 px unter dem
   Seitenanfang. Unterhalb des Haltepunkts, den der Kommentar am Ende der
   Datei schon begründet (767 px: dort ist der Tabelleninhalt mehr als das
   1,3-fache des Fensters, Wischen wird vom Notbehelf zur Bedienung), wird
   jede Zeile eine Karte, die Kennzahlen eine schmale Zeile und die Filter
   ein Knopf. Es ist derselbe Quelltext (`_document_table.html`), nur
   anders dargestellt -- kein zweiter Haltepunkt und keine zweite Liste.
   Die Regeln stehen hier, bei den Tabellenregeln, und stehen nach ihnen:
   `td.pinit-col-nowrap` setzt `width: 1%` und `nowrap` mit derselben
   Stärke, und bei gleicher Stärke gewinnt die spätere Regel. Alle mit
   `.pinit-theme` und dem Tabellennamen davor, aus dem Grund, den die
   Knopfregeln oben nennen. */

/* Am Desktop gibt es die Zeile „Filter" nicht: die Felder stehen offen. */
.pinit-theme .pinit-filters > summary { display: none; list-style: none; }
/* Die Beschriftung neben dem Kästchen in der Kopfzeile gibt es nur in der
   Kartenansicht, wo die Spaltenköpfe fehlen. */
.pinit-theme .pinit-doc-select-all { display: none; }
/* „Kopieren" in der Spalte „Link"; in der Karte fehlt die Spaltenüberschrift,
   dort heisst der Knopf „Link kopieren". */
.pinit-theme .pinit-doc-narrow-only { display: none; }

/* „Als Nächstes" auf der Dokumentseite: der Kasten und, bei einem leeren
   Dokument, die Ablagefläche tragen einen Strich am Rand. Es ist die eine
   Stelle der Seite, an der jetzt etwas zu tun ist, und sie soll das zeigen,
   bevor sie etwas erklärt. */
.pinit-theme .pinit-next { border-left: 4px solid var(--pinit-color-primary); }
/* Die schmale Spalte des Kästchens. Früher stand die Breite als `style` an
   der Zelle; ein `style` ist stärker als jede Regel hier und hätte der
   Kartenansicht die Breite von 32 px aufgezwungen. */
.pinit-theme .pinit-doc-table th.pinit-doc-select { width: 32px; }
/* Art und Marke als graue Zeile unter dem Titel (story-044). Sie waren zwei
   Spalten von zusammen 196 px, und mit ihnen war die Tabelle bei einem
   Fenster von 1280 px 40 px breiter als ihr Kasten (1270 gegen 1230 px);
   ohne sie braucht sie 1074 px. Die Schrift kommt von `.meta`, hier steht
   nur der Abstand zum Titel. */
.pinit-theme .pinit-doc-table .pinit-doc-meta { margin-top: 2px; }

@media (max-width: 767px) {
  /* Filter: nur die Zeile, die Felder dahinter. */
  .pinit-theme .pinit-filters { padding: 0 var(--pinit-space-4); }
  .pinit-theme .pinit-filters > summary {
    display: flex;
    align-items: center;
    gap: var(--pinit-space-2);
    min-height: 44px;
    cursor: pointer;
    font-weight: 500;
  }
  .pinit-theme .pinit-filters > summary::after { content: "\25BE"; margin-left: auto; }
  .pinit-theme .pinit-filters[open] > summary::after { content: "\25B4"; }
  .pinit-theme .pinit-filters[open] > form { padding-bottom: var(--pinit-space-4); }

  /* Kennzahlen: vier schmale Kapseln in zwei Spalten statt vier hoher
     Kacheln. Zahl und Beschriftung nebeneinander. In eine einzige Zeile
     passen die vier bei 375 px nicht (zusammen gut 400 px), und eine
     ausgefranste zweite Zeile sieht schlechter aus als zwei gleiche. */
  .pinit-dashboard-strip {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--pinit-space-2);
    margin-bottom: var(--pinit-space-3);
  }
  .pinit-theme a.pinit-stat {
    display: flex;
    align-items: baseline;
    justify-content: flex-start;
    gap: 6px;
    padding: 6px var(--pinit-space-3);
    margin-bottom: 0;
  }
  .pinit-theme a.pinit-stat .pinit-stat-number { display: inline; font-size: 16px; }

  /* Die Tabelle wird eine Liste von Karten. */
  .pinit-theme .pinit-doc-table,
  .pinit-theme .pinit-doc-table thead,
  .pinit-theme .pinit-doc-table tbody { display: block; }

  /* Von der Kopfzeile bleibt nur „Alle auswählen". */
  .pinit-theme .pinit-doc-table thead tr {
    display: flex;
    padding: var(--pinit-space-3) var(--pinit-space-4);
    background: var(--pinit-color-surface-muted);
    border-bottom: 1px solid var(--pinit-color-border-light);
  }
  .pinit-theme .pinit-doc-table thead th { display: none; }
  .pinit-theme .pinit-doc-table thead th.pinit-doc-select {
    display: flex;
    align-items: center;
    gap: var(--pinit-space-3);
    width: auto;
    padding: 0;
    border: 0;
    background: none;
  }
  .pinit-theme .pinit-doc-select-all { display: inline; }
  .pinit-theme .pinit-doc-wide-only { display: none; }
  .pinit-theme .pinit-doc-narrow-only { display: inline; }

  .pinit-theme .pinit-doc-table tbody tr {
    display: grid;
    grid-template-columns: 20px minmax(0, 1fr) auto;
    grid-template-areas:
      "select title title"
      ".      customer customer"
      ".      status status"
      ".      link actions";
    align-items: center;
    column-gap: var(--pinit-space-3);
    row-gap: 6px;
    padding: var(--pinit-space-3) var(--pinit-space-4);
    border-bottom: 1px solid var(--pinit-color-border-light);
  }
  .pinit-theme .pinit-doc-table tbody td {
    display: block;
    width: auto;
    padding: 0;
    border: 0;
    white-space: normal;
  }
  .pinit-theme .pinit-doc-table tbody td.pinit-doc-select { grid-area: select; align-self: start; padding-top: 2px; }
  .pinit-theme .pinit-doc-table tbody td.pinit-doc-title { grid-area: title; font-size: 15px; font-weight: 500; }
  .pinit-theme .pinit-doc-table tbody td.pinit-doc-customer { grid-area: customer; }
  .pinit-theme .pinit-doc-table tbody td.pinit-doc-status { grid-area: status; }
  .pinit-theme .pinit-doc-table tbody td.pinit-doc-link { grid-area: link; }
  /* Ohne Link steht in der Tabelle ein Strich; in einer Karte neben
     „Bearbeiten" wäre er ein Rest ohne Bedeutung. */
  .pinit-theme .pinit-doc-table tbody td.pinit-doc-link .pinit-hint { display: none; }
  .pinit-theme .pinit-doc-table tbody td.pinit-doc-actions { grid-area: actions; text-align: right; }
  /* Was die Karte nicht zeigt: es steht am Desktop und auf der Dokumentseite.
     Freigabe und Geändert sind Zellen; Art und Marke sind seit story-044 die
     graue Zeile unter dem Titel. */
  .pinit-theme .pinit-doc-table tbody td.pinit-doc-access,
  .pinit-theme .pinit-doc-table tbody td.pinit-doc-changed { display: none; }
  .pinit-theme .pinit-doc-table tbody .pinit-doc-meta { display: none; }
  /* Die Zeile „keine Dokumente" hat keinen Bereichsnamen und läge sonst in
     der 20-px-Spalte des Kästchens. */
  .pinit-theme .pinit-doc-table tbody td.pinit-doc-empty { grid-column: 1 / -1; }

  /* Die Handgriffe der Karte sind 40 px hoch (Richtwert für Fingerspitzen
     44; die Knöpfe sonst 32). */
  .pinit-theme .pinit-doc-table tbody .pinit-btn-sm { height: 40px; }
  .pinit-theme .pinit-doc-table tbody td.pinit-doc-actions a {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
  }
}

/* Messages */
.pinit-messages { list-style: none; margin: 0 0 var(--pinit-space-4); padding: 0; }
.pinit-messages-page { max-width: var(--pinit-content-max); margin-left: auto; margin-right: auto; padding-top: var(--pinit-space-4); }
/* Every message used to render in error red, because the tag was never
   emitted into the markup -- so "Published release 1." read exactly
   like "Too many failed login attempts." The tag is now on the <li>
   (cotton/messages.html) and each level looks like what it is. */
.pinit-messages li {
  background: var(--pinit-color-surface);
  color: var(--pinit-color-text);
  border: 1px solid var(--pinit-color-border);
  border-radius: var(--pinit-radius-md);
  padding: var(--pinit-space-3) var(--pinit-space-4);
  margin-bottom: var(--pinit-space-2);
  font-size: 13px;
}
.pinit-messages li.success {
  background: rgba(77, 170, 87, 0.12);
  border-color: rgba(77, 170, 87, 0.3);
  color: var(--pinit-color-success-text);
}
.pinit-messages li.warning {
  background: rgba(242, 169, 59, 0.16);
  border-color: rgba(242, 169, 59, 0.35);
  color: var(--pinit-color-warning-text);
}
.pinit-messages li.error {
  background: rgba(216, 67, 67, 0.1);
  border-color: rgba(216, 67, 67, 0.25);
  color: var(--pinit-color-error-text);
}

/* Operational warning inside the Studio shell -- e.g. a brand whose
   domain this environment doesn't answer to (apps/brands/checks.py).
   Warning amber, not the error red the message list uses: nothing is
   broken in the app, something is missing in the environment. */
.pinit-banner-warning {
  display: flex;
  align-items: flex-start;
  gap: var(--pinit-space-3);
  background: rgba(242, 169, 59, 0.12);
  border: 1px solid rgba(242, 169, 59, 0.35);
  border-radius: var(--pinit-radius-md);
  padding: var(--pinit-space-3) var(--pinit-space-4);
  margin-bottom: var(--pinit-space-6);
  font-size: 13px;
}
.pinit-banner-warning .material-symbols-outlined { color: var(--pinit-color-warning); font-size: 20px; }
.pinit-banner-warning p { margin: 0 0 var(--pinit-space-1); }
.pinit-banner-warning code { font-size: 12px; }
.pinit-banner-warning-hint { color: var(--pinit-color-text-muted); }

.pinit-actions { display: flex; align-items: center; gap: var(--pinit-space-3); flex-wrap: wrap; }
.pinit-form-inline { display: inline; }
.pinit-hint { color: var(--pinit-color-text-muted); font-size: 13px; }
/* The <p class="pinit-hint" style="margin:8px 0 0"> idiom, which
   appeared ten times across the templates. */
.pinit-note { display: block; margin: var(--pinit-space-2) 0 0; }
/* ...which silently un-hid every [hidden] element carrying it: a lone
   class beats the browser's own `[hidden] { display: none }`, so the
   "copy the password now" warning stood on the sharing page
   permanently, before any password had been generated. Class plus
   attribute wins it back, for every element rather than that one.
   Found in the browser; `hidden` is still set in the DOM, which is why
   nothing in the markup looked wrong. */
.pinit-theme [hidden] { display: none; }

/* A form does not get wider just because the window does: a 1440px
   text field reads worse, not better. Replaces eight separate inline
   max-widths that had drifted to 480, 520 and 560 for the same kind of
   screen. min() so it still fits a phone. */
.pinit-form-card { max-width: min(560px, 100%); }

/* Das Formular „Neues Dokument" nutzt die ganze Breite (story-045): aus ihm
   entstehen die Dokumente, und mit dem Knopf „Neuer Kunde" neben dem
   Auswahlfeld wurde ein 560-px-Kasten zu eng. Die Felder liegen in einem
   Raster, das von selbst von drei Spalten auf eine schrumpft (kein weiterer
   Haltepunkt): Titel und Beschreibung über die ganze Breite, Kunde, Marke
   und Art nebeneinander. Die Felder verlieren dort die 480-px-Grenze von
   oben; mit `.pinit-field` davor (0-3-1), weil `input[type="text"]` oben
   schon 0-2-1 hat und bei Gleichstand die Reihenfolge entschiede. Die
   übrigen Formulare bleiben bei `.pinit-form-card`. */
.pinit-theme .pinit-form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  column-gap: var(--pinit-space-6);
}
.pinit-theme .pinit-form-grid > .pinit-field-wide { grid-column: 1 / -1; }
.pinit-theme .pinit-form-grid .pinit-field input,
.pinit-theme .pinit-form-grid .pinit-field select,
.pinit-theme .pinit-form-grid .pinit-field textarea { max-width: none; }
/* Auswahlfeld und Knopf in einer Zeile: das Feld gibt nach, der Knopf nicht. */
.pinit-theme .pinit-field-row { display: flex; align-items: center; gap: var(--pinit-space-2); }
.pinit-theme .pinit-field-row select { flex: 1 1 auto; min-width: 0; }
.pinit-theme .pinit-field-row button { flex: none; }

/* Das Fenster „Neuer Kunde" (customers/_quick_create_dialog.html). Kein
   `display` auf dem <dialog> selbst: ein geschlossenes Fenster ist über die
   Regel des Browsers unsichtbar, und ein eigenes `display` risse es wieder
   auf, dieselbe Falle wie bei `[hidden]` oben. */
.pinit-theme .pinit-dialog {
  width: min(480px, calc(100vw - 32px));
  padding: var(--pinit-space-6);
  border: 1px solid var(--pinit-color-border);
  border-radius: var(--pinit-radius-lg);
  background: var(--pinit-color-surface);
  color: var(--pinit-color-text);
  box-shadow: var(--pinit-shadow-card-hover);
}
.pinit-theme .pinit-dialog::backdrop { background: rgba(29, 23, 51, 0.35); }
.pinit-theme .pinit-dialog h2 { margin: 0 0 var(--pinit-space-2); }
.pinit-theme .pinit-field-error {
  display: block;
  margin-top: var(--pinit-space-1);
  font-size: 13px;
  font-weight: 500;
  line-height: 18px;
  color: var(--pinit-color-error-text);
}

/* Drop target for content import. Dashed, quiet, and deliberately not
   the only way in -- the file fields below it keep working. */
.pinit-dropzone {
  border: 2px dashed var(--pinit-color-border);
  border-radius: var(--pinit-radius-lg);
  padding: var(--pinit-space-6);
  text-align: center;
  color: var(--pinit-color-text-muted);
  margin-bottom: var(--pinit-space-4);
  transition: border-color 0.1s ease-in, background 0.1s ease-in;
}
.pinit-dropzone .material-symbols-outlined { font-size: 32px; }
.pinit-dropzone-label { margin: var(--pinit-space-2) 0 0; font-size: 13px; }
.pinit-dropzone.is-dragover {
  border-color: var(--pinit-color-primary-text);
  background: var(--pinit-color-primary-soft);
}
.pinit-dropzone.has-file { border-style: solid; border-color: var(--pinit-color-success-text); }

/* Bare/public pages that still want the theme's typography without the
   full app shell (login, password gate) */
.pinit-bare {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--pinit-space-6);
}
.pinit-bare-card {
  width: 100%;
  max-width: 360px;
}
.pinit-bare-logo { display: flex; justify-content: center; margin-bottom: var(--pinit-space-6); }
.pinit-bare-logo img { height: 28px; }
/* A brand with no uploaded logo file (see cotton/brand_logo.html) still
   gets its own name here, not a silently-wrong default logo. */
.pinit-bare-logo-text {
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--pinit-color-text);
}

/* Per-brand footer under the card on customer-facing pages (company,
   contact, legal notice -- Brand.footer_html). Muted and small: it
   identifies the brand without competing with the document. */
.pinit-bare-footer {
  max-width: 420px;
  margin: var(--pinit-space-6) auto 0;
  padding: 0 var(--pinit-space-4) var(--pinit-space-8);
  color: var(--pinit-color-text-muted);
  font-size: 12px;
  line-height: 18px;
  text-align: center;
}
.pinit-bare-footer a { color: var(--pinit-color-text-muted); }

/* ---------------------------------------------------------------------
   Studio home

   The page used to repeat the navigation in three tiles and show no
   number at all. It now answers three questions, so the type carries
   the answer: one large statement, three counts, and the documents
   behind each one.
   --------------------------------------------------------------------- */

.pinit-hero {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--pinit-space-3);
  margin-bottom: var(--pinit-space-6);
  padding: var(--pinit-space-8) 0 var(--pinit-space-6);
}
.pinit-hero-logo { height: 30px; width: auto; margin-bottom: var(--pinit-space-2); }
.pinit-theme .pinit-hero-title {
  font-size: 38px;
  line-height: 44px;
  font-weight: 300;
  margin: 0;
  max-width: 20ch;
}
/* The number is the message, so it is the one thing set in the brand
   colour -- the readable variant, which is the same value the primary
   button fills with. */
.pinit-hero-count {
  font-weight: 700;
  color: var(--pinit-color-primary-text);
}
.pinit-hero-lead { color: var(--pinit-color-text-muted); margin: 0; max-width: 56ch; }
.pinit-hero-actions { margin-top: var(--pinit-space-2); }

.pinit-panel-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--pinit-space-4);
  margin-bottom: var(--pinit-space-4);
}
.pinit-panel { display: flex; flex-direction: column; }
/* An empty state keeps its box rather than disappearing: a panel that
   only shows up when something is wrong makes the page a different
   shape on every visit, and nobody learns where anything is. */
.pinit-panel-empty { opacity: 0.72; }
.pinit-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--pinit-space-2);
}
.pinit-panel-icon { font-size: 22px; color: var(--pinit-color-text-muted); }
.pinit-panel-count { font-size: 30px; line-height: 1; font-weight: 600; }
.pinit-theme .pinit-panel h2 { font-size: 15px; margin: 0 0 var(--pinit-space-1); }
/* Zahl und Titel eines Kastens führen in die Liste, wenn der Kasten etwas
   enthält. Sie bleiben in Textfarbe -- ein Verweis, der sich als
   Überschrift gibt; unterstrichen wird erst beim Daraufzeigen (das liefert
   `.pinit-theme a:hover` schon). */
.pinit-theme a.pinit-panel-count,
.pinit-theme .pinit-panel h2 a { color: inherit; }
.pinit-panel-list {
  list-style: none;
  margin: var(--pinit-space-4) 0 0;
  padding: var(--pinit-space-4) 0 0;
  border-top: 1px solid var(--pinit-color-border-light);
  display: grid;
  gap: var(--pinit-space-3);
}
.pinit-panel-list li { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.pinit-panel-list a { font-weight: 500; }

/* Tiles, not rows. As one row per item at 1440px the title sat at the
   far left and its date at the far right with about a thousand pixels
   of nothing between them -- technically aligned, unreadable in
   practice. Tiles keep each title next to its own metadata and use the
   same width the panels above already use. */
.pinit-recent-list {
  list-style: none;
  margin: var(--pinit-space-4) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--pinit-space-3);
}
.pinit-recent-list li {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
  padding: var(--pinit-space-3);
  border: 1px solid var(--pinit-color-border-light);
  border-radius: var(--pinit-radius-sm);
}
.pinit-recent-list a { font-weight: 500; }
.pinit-theme .pinit-recent h2 { font-size: 15px; margin: 0; }

/* ---------------------------------------------------------------------
   Brand page

   Marken hatten bisher keinen eigenen Bildschirm. Das Besondere hier
   ist die Vorschau: sie ist echtes, lebendes Markup, nicht ein Bild.
   Möglich, weil die Marken-Tokens benutzerdefinierte Eigenschaften
   sind und damit auf jedem Element gelten -- ein style-Attribut auf
   .pinit-preview wirkt für alles darin genauso wie auf <body>.
   --------------------------------------------------------------------- */

.pinit-hint-tight { margin: var(--pinit-space-3) 0 0; }

.pinit-brand-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: var(--pinit-space-4);
}
.pinit-brand-card { display: flex; flex-direction: column; gap: var(--pinit-space-4); }
.pinit-brand-card-head {
  display: flex;
  align-items: center;
  min-height: 56px;
  padding-bottom: var(--pinit-space-4);
  border-bottom: 1px solid var(--pinit-color-border-light);
}
.pinit-brand-card-logo { height: 26px; width: auto; max-width: 100%; }
.pinit-brand-card-name { font-size: 18px; font-weight: 600; }
.pinit-brand-card-colors { display: flex; gap: var(--pinit-space-2); }
.pinit-brand-card-foot { margin-top: auto; }

/* Not two equal halves: the left column holds the brand's facts and
   grows with them, while the right holds a preview of a 320px customer
   page plus a short list -- it cannot use half of 1440px. Measured at
   1440 with equal columns: 543px against 1029px, i.e. roughly 480px of
   empty left column. */
.pinit-brand-profile {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: var(--pinit-space-4);
  align-items: start;
}
.pinit-brand-profile > div { display: flex; flex-direction: column; gap: var(--pinit-space-4); }
.pinit-theme .pinit-brand-profile h2 { font-size: 15px; margin: 0 0 var(--pinit-space-4); }

.pinit-brand-facts { display: grid; grid-template-columns: auto 1fr; gap: var(--pinit-space-2) var(--pinit-space-4); margin: 0; }
.pinit-brand-facts dt { color: var(--pinit-color-text-muted); font-size: 13px; }
.pinit-brand-facts dd { margin: 0; display: flex; align-items: center; gap: var(--pinit-space-2); flex-wrap: wrap; }

/* Assets are read, never uploaded: MEDIA isn't served in production and
   the container has no persistent volume. The chequerboard is so a white
   logo on white is still visibly a logo and not a blank box. */
.pinit-brand-assets { display: flex; gap: var(--pinit-space-6); flex-wrap: wrap; }
.pinit-brand-assets figure { margin: 0; display: flex; flex-direction: column; gap: var(--pinit-space-2); }
.pinit-brand-assets figcaption { font-size: 13px; display: flex; flex-direction: column; }
.pinit-asset-frame {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 180px;
  height: 72px;
  padding: var(--pinit-space-3);
  border: 1px solid var(--pinit-color-border-light);
  border-radius: var(--pinit-radius-md);
  background-color: var(--pinit-color-surface);
  background-image:
    linear-gradient(45deg, var(--pinit-color-surface-muted) 25%, transparent 25%),
    linear-gradient(-45deg, var(--pinit-color-surface-muted) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, var(--pinit-color-surface-muted) 75%),
    linear-gradient(-45deg, transparent 75%, var(--pinit-color-surface-muted) 75%);
  background-size: 12px 12px;
  background-position: 0 0, 0 6px, 6px -6px, -6px 0;
}
.pinit-asset-frame img { max-width: 100%; max-height: 100%; }
.pinit-asset-frame-sm { width: 72px; }
.pinit-asset-missing { color: var(--pinit-color-text-muted); font-size: 13px; background-image: none; }

.pinit-swatch-rows { display: flex; flex-direction: column; gap: var(--pinit-space-4); }
.pinit-swatch-row { display: flex; align-items: center; gap: var(--pinit-space-4); flex-wrap: wrap; }
.pinit-swatch-pair { display: flex; gap: var(--pinit-space-1); }
.pinit-swatch {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  width: 84px;
  height: 56px;
  border-radius: var(--pinit-radius-sm);
  border: 1px solid rgba(0, 0, 0, 0.08);
}
.pinit-swatch-sm { width: 28px; height: 28px; }
/* White on any swatch: both values clear 4.5:1 against white by
   construction, and contrast is symmetric, so white on them is just as
   safe (apps/shared/services/color.py). */
.pinit-swatch-hex {
  font-size: 10px;
  letter-spacing: 0.04em;
  color: #FFFFFF;
  background: rgba(0, 0, 0, 0.35);
  border-radius: var(--pinit-radius-sm);
  padding: 1px var(--pinit-space-1);
  margin-bottom: var(--pinit-space-1);
}
/* align-items, or a badge in this column stretches to the full
   width of the widest line next to it. */
.pinit-swatch-meta { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }

/* A real page, scaled down inside a card -- not a screenshot, so it can
   never drift from what the customer sees. */
.pinit-preview {
  border: 1px solid var(--pinit-color-border-light);
  border-radius: var(--pinit-radius-md);
  background: var(--pinit-color-app-bg);
  padding: var(--pinit-space-6) var(--pinit-space-4);
}
.pinit-preview-page { max-width: 320px; margin: 0 auto; }
.pinit-preview .pinit-bare-footer { margin-top: var(--pinit-space-4); }
/* The preview's own controls are inert: a disabled input that still
   looks greyed out would misrepresent the page it is previewing. */
.pinit-preview input[disabled],
.pinit-preview button[disabled] { opacity: 1; cursor: default; }

/* The strip that says which brand the content column has adopted.
   Quiet on purpose: it explains a colour change, it is not an
   announcement. */
.pinit-brand-strip {
  display: flex;
  align-items: center;
  gap: var(--pinit-space-3);
  margin: 0 0 var(--pinit-space-4);
  padding: var(--pinit-space-2) var(--pinit-space-3);
  border: 1px solid var(--pinit-color-border-light);
  border-left: 3px solid var(--pinit-color-primary);
  border-radius: var(--pinit-radius-sm);
  background: var(--pinit-color-surface);
  color: var(--pinit-color-text-muted);
  font-size: 13px;
}
.pinit-brand-strip img { height: 18px; width: auto; }

.pinit-brand-scope { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--pinit-space-2); }
.pinit-brand-scope li { display: flex; align-items: center; gap: var(--pinit-space-2); }
.pinit-scope-yes { color: var(--pinit-color-success-text); }
.pinit-scope-fixed { color: var(--pinit-color-text-muted); }

/* ---------------------------------------------------------------------
   Breakpoints

   Two, both max-width, both measured rather than chosen from a list of
   devices. The rule for adding a third: name the content that forced it
   and the width you measured, in a comment here. Not a device name.

   There is deliberately no min-width query anywhere: .pinit-main is
   capped at --pinit-content-max (1440px), so above ~1488px the layout
   is frozen by that cap rather than by a query.
   --------------------------------------------------------------------- */

/* 899px -- the topbar's children (brand + three labelled nav items +
   Admin + the signed-in address + Log out) stop fitting on one line just
   under 900px. Measured at 758px of content in a 375px window before
   this rule existed: the document itself scrolled sideways on every
   Studio page, which the table-scroll comment above says must never
   happen. */
@media (max-width: 899px) {
  .pinit-topbar { flex-wrap: wrap; row-gap: var(--pinit-space-2); }
  .pinit-nav { flex: 1 0 100%; order: 3; margin-left: 0; overflow-x: auto; }
  .pinit-topbar-spacer { display: none; }
  /* The address is the single widest item and the least needed in the
     chrome; the Studio home shows it instead. */
  .pinit-user-email { display: none; }
  .pinit-user { margin-left: auto; }
  .pinit-brand-name { font-size: 15px; }
}

/* 767px -- tablet portrait, and the width at which the documents table's
   remaining content is more than 1.3x the viewport, i.e. where sideways
   scrolling stops being an inconvenience and becomes the interaction. */
@media (max-width: 767px) {
  .pinit-main { padding: var(--pinit-space-4); }
  /* Icon-only actions: the label is still in the DOM for screen
     readers, just not painted. */
  .pinit-action-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .pinit-theme .pinit-btn-sm { padding: 0 var(--pinit-space-2); }
  /* Form cards stop being narrower than the screen they sit on. */
  .pinit-card { padding: var(--pinit-space-4); }
  .pinit-theme h1 { font-size: 18px; line-height: 26px; }
  /* The brand profile's two columns stack. Its widest fixed element is
     the 180px logo frame, which still fits a 375px window with the
     card's own padding. */
  .pinit-brand-profile { grid-template-columns: minmax(0, 1fr); }
  .pinit-theme .pinit-hero-title { font-size: 26px; line-height: 32px; }
  .pinit-hero { padding: var(--pinit-space-6) 0 var(--pinit-space-4); }
}

/* --- Assistent: ein KI-Chat (story-039, story-046) ------------------
   Die Schnellaktionen sind Radiofelder mit <label>, die Auswahlfelder
   stecken in Labels, der Sende-Knopf ist ein <button>. Darum sind die
   Regeln dafür als Klasse+Klasse geschrieben (.pinit-theme .pinit-chip):
   `.pinit-theme label` setzt 12px, grau und display:block, `.pinit-theme
   button` den Hauptknopf, und eine einzelne Klasse verlöre gegen beides --
   dieselbe Falle, die in CLAUDE.md für die Knöpfe beschrieben ist, nur mit
   anderen Elementen. Im Browser nachgesehen, nicht hergeleitet.

   Volle Breite: kein max-width auf .pinit-chat. Es stand auf 60rem, und das
   Formular davor auf 560 px; beides war der Anlass zu „Boxen auf die
   gesamte Breite" (story-046). Der Text in den Boxen behält seine lesbare
   Zeilenlänge (.pinit-chat-body). */

/* Nur für Hilfsmittel und die Tastatur: die Beschriftung eines Feldes, das
   optisch schon durch sein Umfeld erklärt ist (Textfläche, Auswahlfelder). */
.pinit-theme .pinit-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.pinit-chat { display: flex; flex-direction: column; gap: var(--pinit-space-4); }
.pinit-chat-header > p { margin: 0 0 var(--pinit-space-2); }
.pinit-chat-start { padding-top: var(--pinit-space-6); gap: var(--pinit-space-3); }
.pinit-theme .pinit-chat-title {
  margin: 0;
  text-align: center;
  font-size: 32px;
  line-height: 40px;
  font-weight: 300;
}
.pinit-chat-lead { margin: 0 auto var(--pinit-space-3); max-width: 60ch; text-align: center; color: var(--pinit-color-text-muted); }

.pinit-chat-context { display: flex; flex-wrap: wrap; gap: var(--pinit-space-3); font-size: 12px; color: var(--pinit-color-text-muted); margin: 0; }
.pinit-chat-context strong { color: var(--pinit-color-text); font-weight: 500; }

.pinit-chat-thread { display: flex; flex-direction: column; gap: var(--pinit-space-3); }
.pinit-chat-empty { color: var(--pinit-color-text-muted); text-align: center; padding: var(--pinit-space-6) 0; margin: 0; }

/* Jeder Beitrag ist eine Box auf der ganzen Breite, mit einer Marke links:
   eine Sprechblasen-Optik wäre bei der Länge eines Dokumententwurfs
   unlesbar, und der Nutzer wollte die Boxen breit. */
.pinit-chat-msg {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr);
  column-gap: var(--pinit-space-3);
  row-gap: 2px;
  align-items: start;
  background: var(--pinit-color-surface);
  border: 1px solid var(--pinit-color-border-light);
  border-radius: var(--pinit-radius-md);
  padding: var(--pinit-space-3) var(--pinit-space-4);
}
.pinit-chat-msg > :not(.pinit-chat-avatar) { grid-column: 2; }
.pinit-chat-msg-user { background: var(--pinit-color-surface-muted); }
.pinit-chat-avatar {
  grid-row: 1 / span 4;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--pinit-color-border-light);
  color: var(--pinit-color-text-muted);
}
.pinit-chat-avatar .material-symbols-outlined { font-size: 20px; }
.pinit-chat-msg-assistant .pinit-chat-avatar { background: var(--pinit-color-primary-soft); color: var(--pinit-color-primary-text); }
.pinit-chat-meta { font-size: 12px; color: var(--pinit-color-text-muted); margin: 0; }
.pinit-chat-body { white-space: pre-wrap; margin: 0; max-width: 90ch; }
.pinit-chat-actions { margin: var(--pinit-space-2) 0 0; }
.pinit-chat-note { margin: var(--pinit-space-1) 0 0; }

/* „Wird erzeugt": drei Punkte, die nacheinander aufleuchten. Wer
   Bewegung abgestellt hat, sieht sie ruhig stehen. */
.pinit-chat-working { display: flex; gap: var(--pinit-space-1); margin: var(--pinit-space-2) 0 0; }
.pinit-chat-working span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--pinit-color-primary);
  opacity: 0.3;
  animation: pinit-pulse 1.2s ease-in-out infinite;
}
.pinit-chat-working span:nth-child(2) { animation-delay: 0.2s; }
.pinit-chat-working span:nth-child(3) { animation-delay: 0.4s; }
@keyframes pinit-pulse { 0%, 80%, 100% { opacity: 0.25; } 40% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .pinit-chat-working span { animation: none; opacity: 0.6; }
}

/* Die Eingabe: eine runde Fläche mit Textfläche oben und Auswahl und
   Sende-Knopf unten, wie man es von einem KI-Chat kennt. */
.pinit-composer { display: flex; flex-direction: column; gap: var(--pinit-space-3); }
/* Sie klebt nicht am unteren Rand des Fensters, wie es manche Chats tun: mit
   den Schnellaktionen und ihren Sätzen ist die Eingabe gut 230 px hoch, auf
   dem Handy mehr als die Hälfte des Bildschirms, und ein Verlauf besteht hier
   aus wenigen langen Beiträgen, nicht aus vielen kurzen. (Gemessen: 478 von
   812 px am Handy; deshalb nicht.) */
.pinit-composer-box {
  display: flex;
  flex-direction: column;
  gap: var(--pinit-space-2);
  padding: var(--pinit-space-3) var(--pinit-space-4);
  background: var(--pinit-color-surface);
  border: 1px solid var(--pinit-color-border);
  border-radius: 24px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
.pinit-composer-box:focus-within {
  border-color: var(--pinit-color-primary-text);
  box-shadow: 0 0 0 3px var(--pinit-color-primary-soft);
}
/* Textfläche und Titel sitzen ohne eigenen Rahmen in der Fläche: die Fläche
   ist das Feld. Eigene Schrift (nicht die Festbreitenschrift des Einfügefelds
   für Quelltext) und 16 px, damit das Handy beim Antippen nicht zoomt.
   Mit `.pinit-composer-box` davor (0-3-1), weil `.pinit-theme textarea:focus`
   den Rahmen sonst wieder setzte. */
.pinit-theme .pinit-composer-box textarea,
.pinit-theme .pinit-composer-box textarea:focus {
  width: 100%;
  max-width: none;
  height: auto;
  min-height: 3.25rem;
  padding: var(--pinit-space-1) 0;
  border: 0;
  box-shadow: none;
  background: transparent;
  font-family: inherit;
  font-size: 16px;
  line-height: 24px;
  resize: none;
}
.pinit-theme .pinit-composer-box .pinit-composer-title,
.pinit-theme .pinit-composer-box .pinit-composer-title:focus {
  max-width: none;
  height: 32px;
  padding: 0;
  border: 0;
  border-bottom: 1px solid var(--pinit-color-border-light);
  border-radius: 0;
  box-shadow: none;
  background: transparent;
  font-size: 14px;
}

.pinit-composer-bar { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--pinit-space-2); }
.pinit-composer-selects { display: flex; flex-wrap: wrap; align-items: center; gap: var(--pinit-space-2); min-width: 0; flex: 1 1 auto; }
.pinit-composer-pill-group { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--pinit-space-1); }
/* Der Knopf bricht nicht in zwei Zeilen um; reicht der Platz nicht, rutscht er
   unter die Kapsel (gemessen am Handy: „Neuer / Kunde" in einer schmalen Spalte). */
.pinit-theme .pinit-composer-pill-group button { white-space: nowrap; }
/* Ein Auswahlfeld als Kapsel: eine kleine Beschriftung und der gewählte Wert,
   der Rahmen gehört der Kapsel, nicht dem Feld darin. */
.pinit-theme .pinit-composer-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--pinit-space-1);
  margin: 0;
  padding: 0 var(--pinit-space-1) 0 var(--pinit-space-3);
  height: 32px;
  border: 1px solid var(--pinit-color-border);
  border-radius: 999px;
  background: var(--pinit-color-surface);
  font-size: 12px;
  color: var(--pinit-color-text-muted);
  cursor: pointer;
}
.pinit-theme .pinit-composer-pill:hover { border-color: var(--pinit-color-primary); }
.pinit-theme .pinit-composer-pill:focus-within { border-color: var(--pinit-color-primary-text); box-shadow: 0 0 0 3px var(--pinit-color-primary-soft); }
.pinit-theme .pinit-composer-pill:has(select[aria-invalid="true"]) { border-color: var(--pinit-color-error-text); }
.pinit-theme .pinit-composer-pill select,
.pinit-theme .pinit-composer-pill select:focus {
  width: auto;
  max-width: 14rem;
  height: 30px;
  padding: 0 var(--pinit-space-1) 0 0;
  border: 0;
  box-shadow: none;
  background: transparent;
  font-size: 13px;
  color: var(--pinit-color-text);
  cursor: pointer;
}

/* Der Sende-Knopf: rund, mit Pfeil, wie bei jedem KI-Chat. Aus, solange nichts
   dasteht (pinit-composer.js) und nach dem Abschicken. */
.pinit-theme .pinit-composer-send {
  flex: none;
  width: 40px;
  height: 40px;
  padding: 0;
  border-radius: 50%;
  justify-content: center;
}
.pinit-theme .pinit-composer-send .material-symbols-outlined { font-size: 22px; }
.pinit-theme .pinit-composer-send:disabled { background: var(--pinit-color-disabled); cursor: not-allowed; }
.pinit-composer-hint { margin: 0; }

/* Schnellaktionen: die Tätigkeiten als wählbare Kapseln mit Symbol. Das
   Radiofeld ist versteckt, die Auswahl färbt das Label dahinter. */
.pinit-tile-input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.pinit-chat-quick { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--pinit-space-2); border: 0; padding: 0; margin: 0; }
.pinit-chat > .pinit-composer .pinit-chat-quick { justify-content: flex-start; }
.pinit-chat-quick-hint { margin: 0; text-align: center; min-height: 18px; }
.pinit-chat > .pinit-composer .pinit-chat-quick-hint { text-align: left; }

.pinit-theme .pinit-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--pinit-space-1);
  margin: 0;
  padding: 6px 14px 6px 10px;
  border: 1px solid var(--pinit-color-border);
  border-radius: 999px;
  background: var(--pinit-color-surface);
  font-size: 13px;
  line-height: 18px;
  color: var(--pinit-color-text);
  cursor: pointer;
}
.pinit-theme .pinit-chip .material-symbols-outlined { font-size: 18px; color: var(--pinit-color-text-muted); }
.pinit-theme .pinit-chip:hover { border-color: var(--pinit-color-primary); }
.pinit-theme .pinit-tile-input:checked + .pinit-chip {
  border-color: var(--pinit-color-primary-text);
  background: var(--pinit-color-primary-soft);
  color: var(--pinit-color-primary-text);
  font-weight: 500;
}
.pinit-theme .pinit-tile-input:checked + .pinit-chip .material-symbols-outlined { color: var(--pinit-color-primary-text); }
/* Sichtbar für die Tastatur: das Radiofeld selbst ist versteckt, also muss
   der Fokusring auf der Kapsel erscheinen -- sonst ist die Auswahl ohne Maus
   unbedienbar. */
.pinit-theme .pinit-tile-input:focus-visible + .pinit-chip { outline: 2px solid var(--pinit-color-primary); outline-offset: 2px; }

/* Der Kasten auf der Startseite: dieselbe Eingabe, eigene Überschrift. */
.pinit-chat-home { align-self: stretch; width: 100%; margin: var(--pinit-space-2) 0; }
.pinit-theme .pinit-chat-home-title { margin: 0 0 var(--pinit-space-3); font-size: 20px; line-height: 28px; font-weight: 500; }

/* „Zuletzt" unter dem Start-Bildschirm. */
.pinit-chat-recent { margin-top: var(--pinit-space-4); }
.pinit-theme .pinit-chat-recent h2 { margin: 0 0 var(--pinit-space-2); font-size: 14px; font-weight: 500; color: var(--pinit-color-text-muted); }
.pinit-chat-recent-list { list-style: none; margin: 0; padding: 0; background: var(--pinit-color-surface); border: 1px solid var(--pinit-color-border-light); border-radius: var(--pinit-radius-md); }
.pinit-chat-recent-list li { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--pinit-space-2); padding: var(--pinit-space-3) var(--pinit-space-4); border-bottom: 1px solid var(--pinit-color-border-light); }
.pinit-chat-recent-list li:last-child { border-bottom: 0; }

@media (max-width: 767px) {
  /* Auf dem Handy: die Kapseln brechen um, der Knopf bleibt unten rechts; die
     Überschrift ist kleiner. Es ist der vorhandene Haltepunkt, kein dritter
     (test_there_are_still_exactly_two_breakpoints). */
  .pinit-chat-start { padding-top: var(--pinit-space-3); }
  .pinit-theme .pinit-chat-title { font-size: 26px; line-height: 32px; }
  .pinit-composer-box { padding: var(--pinit-space-3); }
  .pinit-theme .pinit-composer-pill select { max-width: 10rem; }
  .pinit-chat-msg { padding: var(--pinit-space-3); }
}
