/* Colours from the Pretty Flower logo: pink wordmark (#ef9ebe), hibiscus
   pinks (#e06990, #cb3c73), plum (#7f2350), yellow stamens (#efd048) and the
   creature's greens (#8eb76a … #215946). Light mode is the print look, on a
   warm paper with white boxes on it, dark mode the black stickers. Text colours meet WCAG AA contrast. */

@font-face {
  /* League Gothic (SIL Open Font License, see fonts/OFL-league-gothic.txt):
     a free condensed face in the style of the logo's wordmark */
  font-family: 'League Gothic';
  src: url('fonts/league-gothic-latin-400.woff2') format('woff2');
  font-display: swap;
}

:root {
  color-scheme: light dark;
  --bg: #f8f1ea;          /* paper: a warm cream, not screen white */
  --fg: #3a1a2b;          /* plum-black */
  --muted: #7a5a68;
  --accent: #b8326a;      /* magenta: what you can do (links, buttons, the chosen chip), nothing else */
  --accent-fg: #ffffff;   /* text on accent */
  --brand: #cb3c73;       /* the wordmark: the logo's deeper hibiscus pink, readable on paper (dark mode: the wordmark pink) */
  --kind-show: #7f2350;   /* shows: the logo's plum, darker than the accent so a show isn't a button */
  --green: #497248;
  --green-soft: #eef4e8;
  --gold: #8a5d00;         /* other events ("Termin") */
  --gold-soft: #fbf0d2;
  --highlight: #efd048;
  --danger: #b42318;      /* errors and "Wirklich löschen?": a red, not the accent */
  --danger-fg: #ffffff;
  --card: #ffffff;        /* a box, ticket or field on the paper */
  --border: #e2b6c8;   /* rules: visible on paper in a bright room (1.6:1) */
  --display: 'League Gothic', 'Arial Narrow', sans-serif;

  /* The scales of the design system (docs/design-system.md): use these, not
     new values. Not colours, so themes and dark mode leave them alone. */
  --text-xs: 0.75rem;     /* tags, the calendar grid */
  --text-s: 0.875rem;     /* secondary text: muted lines, labels, chips */
  --text-m: 1rem;         /* body text, buttons, fields */
  --text-l: 1.125rem;     /* emphasised lines, e.g. a title in a list */
  --display-m: 1.7rem;    /* section headings (h2) */
  --display-l: 2.6rem;    /* page titles */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2.5rem;
  --radius-s: 4px;        /* small things inside others: marks, the grid */
  --radius-m: 8px;        /* cards, fields, buttons */
  --radius-l: 12px;       /* chat bubbles */
  --radius-pill: 999px;   /* chips and tags */
  --tap: 44px;            /* the smallest thing a finger has to hit */
  /* the outline of a field or chip: --muted softened, still 3:1 and more on
     paper and on a box, light and dark (--border is only for rules) */
  --line: color-mix(in srgb, var(--muted) 80%, var(--card));
  /* under the mouse (or the arrow keys) on an entry inside a box, where
     --card, the usual row background, wouldn't show */
  --wash: color-mix(in srgb, var(--border) 35%, var(--card));
}
/* Dark colours apply when the device prefers dark and nobody chose "Hell" in
   the switch, or when "Dunkel" was chosen (data-theme on <html>, see theme.js
   and lib.js). The two blocks must stay identical. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --bg: #141113;
    --fg: #f6e8ee;
    --muted: #b8a3ad;
    --accent: #ef9ebe;
    --accent-fg: #141113;
    --brand: #ef9ebe;
    --kind-show: #b07ad6;
    --danger: #ff8a7a;
    --danger-fg: #141113;
    --green: #8eb76a;
    --green-soft: #1f2a1b;
    --gold: #e3bd5b;
    --gold-soft: #2b2312;
    --card: #1e1a1d;
    --border: #55444c;
  }
}
:root[data-theme='dark'] {
  --bg: #141113;
  --fg: #f6e8ee;
  --muted: #b8a3ad;
  --accent: #ef9ebe;
  --accent-fg: #141113;
  --brand: #ef9ebe;
  --kind-show: #b07ad6;
  --danger: #ff8a7a;
  --danger-fg: #141113;
  --green: #8eb76a;
  --green-soft: #1f2a1b;
  --gold: #e3bd5b;
  --gold-soft: #2b2312;
  --card: #1e1a1d;
  --border: #55444c;
}
@media (prefers-color-scheme: dark) { :root:not([data-theme='light']) .sticker { background: var(--bg); color: var(--fg); outline: 1.5px solid var(--fg); outline-offset: -1.5px; } }
:root[data-theme='dark'] .sticker { background: var(--bg); color: var(--fg); outline: 1.5px solid var(--fg); outline-offset: -1.5px; }
/* A chosen theme also switches built-in controls (date pickers, scrollbars) */
:root[data-theme='light'] { color-scheme: light; }
:root[data-theme='dark'] { color-scheme: dark; }

* { box-sizing: border-box; }
/* where the keyboard is: a clear ring in the accent, everywhere */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* the hidden attribute always wins over a class's display */
[hidden] { display: none !important; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  background: var(--bg);
  color: var(--fg);
  line-height: 1.45;
}

/* the height comes from the logo's padding, not the header's, so the menu's
   entries can reach down to the bottom edge, where the current one's bar sits */
header {
  padding: 0 var(--space-5);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.brand {
  display: flex;
  align-items: center;
  padding-block: var(--space-4);
  gap: var(--space-2);
  text-decoration: none;
  color: var(--brand);
}
.brand img { width: 30px; height: 52px; }
.brand span {
  font-family: var(--display);
  font-size: 2.1rem;
  line-height: 1;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.page-title {
  font-family: var(--display);
  font-weight: normal;
  font-size: var(--display-l);
  line-height: 1.05;
  letter-spacing: 0.01em;
  margin: var(--space-2) 0 var(--space-4);
}
/* The menu (pages/layout.js): every entry an icon with its word. On wider
   screens one row at the top: the places (Termine … Daisy), then, set apart
   by a line, the tools (Aktivität, Suche, Konto), the word under each icon.
   On phones the places are a bar along the bottom, in reach of the thumb, and
   the tools sit beside the logo. "Phones" here means up to 767 px
   (--tabbar's media queries), wider than elsewhere: below that the menu
   doesn't fit beside even the logo's figure, and two rows of icons looked
   muddled (the bar under the current one far from some, close to others).
   From 768 px one row; up to 899 px the logo without its name. */
:root { --tabbar: 3.5rem; }
header nav, .nav-pages, .nav-tools { display: flex; align-items: center; }
header nav { flex-wrap: wrap; justify-content: flex-end; gap: var(--space-2) var(--space-3); }
.nav-pages { gap: var(--space-2); }
/* the line before the tools: half the header's height, now that the entries
   reach from top to bottom */
.nav-tools { gap: var(--space-2); padding-left: var(--space-3); background: linear-gradient(var(--border), var(--border)) left center / 1px 50% no-repeat; }
/* each entry a column, the word under its icon, on every screen: beside it,
   an icon sat about as close to the word before it as to its own, and one
   had to look twice which belonged to which */
header nav a, header nav summary {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-width: 60px;
  min-height: var(--tap); /* a finger high */
  padding: var(--space-1) 2px;
  color: var(--muted);
  text-decoration: none;
  font-size: 0.8125rem;
  line-height: 1.1;
}
header nav a.nav-live { flex-direction: row; }
/* wider screens: a little air between the columns */
@media (min-width: 768px) {
  .nav-pages, .nav-tools { gap: var(--space-4); }
  .nav-tools { padding-left: var(--space-4); }
  header nav { column-gap: var(--space-4); }
}
/* where you are: pink, bold, and a pink bar on the header's bottom edge
   under it (on a phone, along the top of the bottom bar), so it isn't told
   by colour alone. The entries stretch to the header's full height for it */
header nav a.active, header nav summary.active { color: var(--accent); font-weight: 600; }
header nav, .nav-pages, .nav-tools { align-self: stretch; align-items: stretch; }
header nav a, header nav summary { position: relative; }
header nav a.nav-live { align-self: center; }
header nav a.active::after, header nav summary.active::after { content: ''; position: absolute; left: 6px; right: 6px; bottom: -1px; height: 3px; border-radius: 3px 3px 0 0; background: var(--accent); }
/* every word keeps the width of its bold self (an invisible bold copy below
   it), so the entries don't shift when another one becomes the current page */
.nav-label { display: inline-flex; flex-direction: column; align-items: center; }
.nav-label::after { content: attr(data-text); height: 0; overflow: hidden; visibility: hidden; font-weight: 600; user-select: none; pointer-events: none; }
/* where you could go: under the mouse only darker, never pink, so it can't be
   mistaken for where you are. Hover only with a mouse: a phone would colour
   an entry as soon as a finger touches it, even when the touch turns into a
   swipe and opens nothing. No grey flash on iPhones either: the page that
   opens, with its entry highlighted, is the answer to a tap */
@media (hover: hover) { header nav a:not(.active):not(.nav-live):hover, header nav summary:not(.active):hover { color: var(--fg); } }
header nav a, header nav summary { -webkit-tap-highlight-color: transparent; }
.nav-glyph { position: relative; display: inline-flex; }
header nav svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* "Mehr" (pages/layout.js): the third tool, a menu that drops down from its
   icon, at the right edge on every screen, so it opens towards the page */
details.nav-more { position: relative; display: flex; }
details.nav-more > summary { list-style: none; cursor: pointer; user-select: none; }
details.nav-more > summary::-webkit-details-marker { display: none; }
details.nav-more[open] > summary { color: var(--fg); }
.nav-more-panel {
  position: absolute;
  z-index: 900; /* above the bar along the bottom */
  top: 100%;
  right: 0;
  width: 18.5rem;
  max-width: calc(100vw - 2 * var(--space-3));
  margin-top: var(--space-1);
  padding: var(--space-1) 0;
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.15);
  text-align: left;
}
.nav-more-theme { display: grid; gap: var(--space-2); padding: var(--space-2) var(--space-3) var(--space-3); font-size: var(--text-s); }
/* the pages, in groups (pages/layout.js, MORE_GROUPS) without headings:
   the rows of a group close together, a rule between groups with a little
   room around it, so the groups read at a glance; under the mouse --wash
   (the panel is a card) */
.more-pages { display: flex; flex-direction: column; }
.more-group { display: flex; flex-direction: column; }
.more-group + .more-group { border-top: 1px solid var(--border); margin-top: var(--space-1); padding-top: var(--space-1); }
header nav .more-pages a.more-option { flex-direction: row; justify-content: flex-start; align-items: center; gap: var(--space-3); min-width: 0; min-height: var(--tap); padding: var(--space-2) var(--space-3); color: var(--fg); font-size: var(--text-m); }
header nav .more-pages a.more-option[aria-current='page'] { color: var(--accent); font-weight: 600; }
/* "Feedback zu dieser Seite" is a button (it opens a window), drawn as the rows */
header nav .more-pages button.more-option { display: flex; width: 100%; justify-content: flex-start; align-items: center; gap: var(--space-3); min-height: var(--tap); padding: var(--space-2) var(--space-3); background: none; border: 0; border-radius: 0; box-shadow: none; color: var(--fg); font: inherit; font-size: var(--text-m); font-weight: 400; text-align: left; }
header nav .more-pages button.more-option:active { transform: none; }
@media (hover: hover) { header nav .more-pages a.more-option:hover, header nav .more-pages button.more-option:hover { background: var(--wash); } }
/* something new on Aktivität: a dot on the bell */
.nav-dot { position: absolute; top: -2px; right: -3px; width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--accent); }
/* below 1024 px "Zum Training" / "Zur Show" doesn't fit in the row: it gets
   a line of its own under the logo, a passing notice rather than a second
   row of icons */
@media (max-width: 1023px) {
  header nav { display: contents; }
  .nav-pages { margin-left: auto; }
  header nav a.nav-live { order: 2; width: 100%; justify-content: center; }
}
/* tablets and narrow windows: the logo's figure without its name, so the
   menu stays one row */
@media (min-width: 768px) and (max-width: 899px) { .brand span { display: none; } }
@media (max-width: 480px) {
  header { padding: 0 var(--space-3); }
  .brand { padding-block: var(--space-2); }
  .brand span { font-size: 1.8rem; }
}
@media (max-width: 767px) {
  /* the tools as far apart as on wider screens (76 px from icon to icon)
     on every phone from 375 px, for which the logo's name is a little
     smaller there; narrower, only as close together as the logo needs */
  .nav-tools { order: 1; gap: clamp(0px, calc((100vw - 320px) * 0.44), var(--space-5)); padding-left: 0; background: none; margin-right: calc(-1 * var(--space-2)); }
  header nav .nav-tools a, header nav .nav-tools summary { flex-direction: column; justify-content: center; gap: 2px; min-width: 52px; font-size: var(--text-xs); line-height: 1.1; }
  /* the places: a bar along the bottom, above the iPhone's home bar */
  .nav-pages {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 800;
    gap: 0;
    margin-left: 0;
    padding: 0 env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
    background: var(--bg);
    border-top: 1px solid var(--border);
  }
  header nav .nav-pages a { flex: 1 1 0; min-width: 0; height: var(--tabbar); flex-direction: column; justify-content: center; gap: 3px; font-size: var(--text-xs); line-height: 1.1; }
  .nav-pages svg { width: 22px; height: 22px; }
  /* the bar along the top of the bottom bar instead */
  header nav .nav-pages a.active::after { top: -1px; bottom: auto; left: 24%; right: 24%; border-radius: 0 0 3px 3px; }
  .nav-label { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  body:has(.nav-pages) { padding-bottom: calc(var(--tabbar) + env(safe-area-inset-bottom, 0px)); }
}
/* small phones: logo and the three tools still share a line, the tools
   still at their full distance from 375 px */
@media (max-width: 409px) { .brand span { font-size: 1.55rem; } }
@media (max-width: 389px) { .brand span { font-size: 1.35rem; } }
@media (max-width: 359px) { header nav .nav-tools a, header nav .nav-tools summary { min-width: 46px; } }
@media print { .nav-pages { display: none; } }

main {
  max-width: 48rem;  /* a readable column: wider screens get margins, not longer lines */
  margin: 0 auto;
  padding: var(--space-5) var(--space-5) var(--space-6);
}
/* on phones every pixel of width counts, like in an app: narrow side margins
   (the same as the header's), and cards and the gaps between them tighter */
@media (max-width: 480px) {
  main { padding: var(--space-4) var(--space-3) var(--space-6); }
  .card { padding: var(--space-3); border-radius: var(--radius-m); margin-bottom: var(--space-2); }
}

h2 {
  font-family: var(--display);
  font-weight: normal;
  font-size: var(--display-m);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  /* in the text colour: the display face carries a heading, and the accent
     stays for what you can do (links, the main button) and for shows */
  color: var(--fg);
  margin: var(--space-6) 0 var(--space-3);
}
main > h2:first-child { margin-top: var(--space-2); }

.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-m);
  padding: var(--space-4) var(--space-4);
  margin-bottom: var(--space-3);
}

.row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); }
.muted { color: var(--muted); font-size: var(--text-s); }

.pause-card {
  border-style: dashed;
  text-align: center;
  color: var(--muted);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

input, textarea, select, button {
  font: inherit;
  color: inherit;
}
/* a field is never smaller than body text (iOS zooms into anything below
   16px) nor lower than a finger, wherever it sits, e.g. in a smaller label */
input:not([type=checkbox], [type=radio], [type=hidden]), textarea, select { font-size: var(--text-m); }
input:not([type=checkbox], [type=radio], [type=hidden]), select { min-height: var(--tap); }
/* checkboxes a size to hit; ticked is a chosen state, so --fg, not the
   accent (docs/design-system.md) */
input[type=checkbox] { width: 1.375rem; height: 1.375rem; accent-color: var(--fg); flex-shrink: 0; }

input[type=text], input[type=email], input[type=date], input[type=time], input[type=number], textarea, select {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
  padding: var(--space-2) var(--space-2);
  width: 100%;
}
textarea { resize: vertical; min-height: 3.5em; }
/* Safari on iPhone draws date and time fields its own way, which Chrome
   (and our screenshots) never show: a minimum width of its own, so in a
   narrow column they stick out past the screen, centred text, and an empty
   one squashed below the others. Drawn by us instead, they're as wide and
   as high as every other field, the text on the left. */
input[type=date], input[type=time] { display: block; min-width: 0; }
@supports (-webkit-touch-callout: none) {
  input[type=date], input[type=time] { -webkit-appearance: none; appearance: none; text-align: left; }
}
input::-webkit-date-and-time-value { min-height: 1.5em; text-align: left; }

/* Buttons are stickers (docs/design-system.md): solid, a little raised by a
   hard shadow without blur, pressed flat when tapped, a finger high. The main
   one is filled in the accent, raised on a darker accent; a secondary one is
   paper with a visible outline (--muted, 3:1 and more), raised on it. The
   same for links that look like buttons and the summaries of "+ Neu" and
   "Kalender abonnieren". */
button, a.button, details.subscribe > summary {
  --raise: color-mix(in srgb, var(--accent) 55%, #000);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--tap);
  padding: 0 var(--space-4);
  background: var(--accent);
  color: var(--accent-fg);
  border: 1.5px solid var(--raise);
  border-radius: var(--radius-m);
  box-shadow: 0 3px 0 var(--raise);
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.08s ease, box-shadow 0.08s ease;
}
button.secondary, a.button.secondary, details.subscribe:not(.new-menu) > summary {
  --raise: var(--muted);
  background: var(--card);
  color: var(--fg);
}
button:active, a.button:active, details.subscribe > summary:active { transform: translateY(2px); box-shadow: 0 1px 0 var(--raise); }
button:disabled { opacity: 0.5; box-shadow: none; transform: none; cursor: default; }
button svg, a.button svg { width: 18px; height: 18px; flex-shrink: 0; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
/* buttons that aren't stickers: icons, words, chips, the answer switch */
button.icon, button.quiet, button.toggle-chip, button.tip-action, button.tip-star, button.image-choice, button.vote, button.place-chip {
  min-height: 0;
  border: 0;
  box-shadow: none;
  font-weight: inherit;
  transform: none;
}
/* the text editor's toolbar: small secondaries, less raised */
button.fmt-button { min-height: 2.25rem; box-shadow: none; } /* the toolbar is flat: it's a tool, not an action */
/* A quiet button (docs/design-system.md): a word in the accent, no outline,
   still a finger high, for the side actions of a list entry (Bearbeiten,
   Löschen, Antworten) */
button.quiet.quiet-muted { color: var(--muted); }
button.quiet { min-height: var(--tap); padding: 0 var(--space-2); background: none; border: 0; color: var(--fg); font-weight: 600; } /* a side action: --fg, not the accent (design system, "How much colour") */
@media (hover: hover) { button.quiet:hover { text-decoration: underline; opacity: 1; } }
button.icon {
  background: transparent;
  color: var(--muted);
  padding: 0.2rem var(--space-2);
}
@media (hover: hover) {
  button:not(:disabled):hover, a.button:hover, details.subscribe > summary:hover { opacity: 1; filter: brightness(1.06); }
  /* brightening white shows nothing: a secondary button gets --wash
     ("Ändern" and quiet ones like "Löschen" stay words that underline) */
  button.secondary:not(:disabled):not(.edit-section):not(.quiet):hover, a.button.secondary:hover { background: var(--wash); filter: none; }
}

/* Fields in two columns: what belongs together side by side (Datum and Bis,
   Beginn and Ende), the rest (.full) across. minmax(0, …): a column never
   grows past half because of what's in it (Safari's date field would). */
.form-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}
.form-grid > * { min-width: 0; }
.form-grid textarea, .form-grid .full { grid-column: 1 / -1; }
/* on phones one field per line, only Beginn and Ende (.pair) side by side:
   half a phone is too narrow for a place or a date */
@media (max-width: 480px) {
  .form-grid > * { grid-column: 1 / -1; }
  .form-grid > .pair { grid-column: auto; }
}

/* A tag says what something is (a category, "Gast", "Admin"): neutral.
   Green and gold only for the kinds of events they stand for. */
.tag {
  display: inline-block;
  font-size: var(--text-xs);
  padding: 0.1rem var(--space-2);
  border-radius: var(--radius-pill);
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  font-weight: 600;
  text-transform: capitalize;
}

.show-list-item {
  display: block;
  text-decoration: none;
  color: inherit;
}
/* Shows and Trainings: a coming one is a ticket (a link as a whole), with a
   show's poster on the right; a past one a line in the archive */
a.ticket { color: var(--fg); text-decoration: none; }
.ticket .tag { text-transform: none; }
a.ticket .ticket-title, a.ticket .muted { display: block; }
@media (hover: hover) { a.ticket:hover .ticket-title { text-decoration: underline; text-decoration-color: var(--kind); text-decoration-thickness: 2px; } }
.show-ticket-body { min-width: 0; }
/* A show's poster on its ticket (Shows page): whole, never cropped,
   centred in a fixed column at the ticket's right edge, so posters line up
   from ticket to ticket. Where the ticket is too narrow for the poster
   beside the whole answer switch (phones, but also a large phone on its
   side, a split screen or a larger text size), it sits beside the text and
   the switch goes below, full width. Measured on the ticket, in rem, not
   on the screen: a screen-width rule cut "Ich kann nicht" off just above
   it. */
.show-card.ticket { container-type: inline-size; }
.ticket-body.has-poster { display: grid; grid-template-columns: minmax(0, 1fr) 10rem; grid-template-rows: auto auto; column-gap: var(--space-4); }
.ticket-body.has-poster > .show-ticket-body { grid-column: 1; grid-row: 1; }
.ticket-body.has-poster > .answer { grid-column: 1; grid-row: 2; }
.ticket-poster { grid-column: 2; grid-row: 1 / span 2; place-self: center; width: auto; height: auto; max-width: 10rem; max-height: 7.5rem; border-radius: var(--radius-m); }
@container (max-width: 36rem) {
  .ticket-body.has-poster { grid-template-columns: minmax(0, 1fr) 6rem; }
  .ticket-body.has-poster > .answer { grid-column: 1 / -1; }
  .ticket-poster { grid-row: 1; max-width: 6rem; max-height: 5.5rem; }
}
/* how many said yes and no: "✓ 5  ✕ 2", the marks of the cast list */
.answer-count { display: flex; width: fit-content; align-items: baseline; gap: var(--space-3); margin-top: var(--space-1); font-size: var(--text-s); font-variant-numeric: tabular-nums; }
.answer-count-yes { color: var(--green); font-weight: 700; }
.archive { border-top: 2px solid var(--fg); }
.archive-row { display: grid; grid-template-columns: 7.5rem 1fr; gap: 0 var(--space-3); align-items: baseline; padding: var(--space-3); border-bottom: 1px solid var(--border); color: var(--fg); text-decoration: none; }
.archive-date { font-family: var(--display); font-size: var(--text-l); letter-spacing: 0.03em; color: var(--muted); }
.archive-title { font-weight: 600; overflow-wrap: anywhere; }
.archive-row .training-status { grid-column: 2; }
.archive-row .training-status.to-do { color: var(--fg); font-weight: 600; }
.archive-row.cancelled .archive-title { text-decoration: line-through; }
@media (hover: hover) { .archive-row:hover { background: var(--card); } .archive-row:hover .archive-title { text-decoration: underline; } }
@media (max-width: 480px) { .archive-row { grid-template-columns: 6rem 1fr; } }
.show-thumbnail {
  width: 56px;
  height: 56px;
  flex-shrink: 0;
  border-radius: var(--radius-m);
  object-fit: cover;
}
.show-details { display: flex; align-items: flex-start; gap: var(--space-4); }
/* On an event's page the details are the billing of a programme, not a box:
   between a heavy and a thin rule, when and where set big in the display
   face (docs/design-system.md). Changing them is a form, in a box again. */
div.card.show-details { margin: 0 0 var(--space-2); padding: var(--space-4) 0; background: none; border: 0; border-top: 2px solid var(--fg); border-bottom: 1px solid var(--border); border-radius: 0; }
/* … but "Neue Show" is a form like "Neues Training" and "Neuer Termin": a box */
div.card.show-details.show-edit { margin-bottom: var(--space-3); padding: var(--space-4); background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-m); }
@media (max-width: 480px) { div.card.show-details.show-edit { padding: var(--space-3); } }
.details-when { font-family: var(--display); font-size: var(--display-m); line-height: 1.1; letter-spacing: 0.02em; }
.details-when { margin-bottom: 0; }
.details-time { white-space: nowrap; }
.details-where { margin: var(--space-1) 0 0; color: var(--muted); }
.show-details-body .feedback-message:empty { display: none; }
.show-details-body { flex: 1; min-width: 0; }
/* A show's poster in its billing: whole, never cropped, centred in a fixed
   column on the right, as on its ticket on the Shows page. On phones that
   column left the billing half the width, so the poster goes below it */
.details-poster { display: flex; flex: 0 0 10rem; align-self: center; justify-content: center; }
.details-poster img { display: block; max-width: 10rem; max-height: 7.5rem; border-radius: var(--radius-m); }
@media (max-width: 480px) {
  div.card.show-details:not(.show-edit) { flex-wrap: wrap; }
  .show-details > button.edit-section { order: 2; }
  .details-poster { order: 3; flex-basis: 100%; justify-content: flex-start; margin-top: var(--space-1); }
}
/* "Ändern" on a section of a show's or training's page (event-page.js) */
.section-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin: var(--space-6) 0 var(--space-3); }
.section-head h2 { margin: 0; }
/* a finger high, and the same everywhere: pencil and "Ändern" */
/* "Ändern" is a quiet button (pencil and word in the accent, no sticker):
   on a page with several sections, a row of raised buttons drowned the one
   that matters */
button.edit-section, a.edit-section { gap: var(--space-1); flex-shrink: 0; min-width: var(--tap); padding: 0 var(--space-2); background: none; border: 0; box-shadow: none; color: var(--fg); }
@media (hover: hover) { button.edit-section:hover { text-decoration: underline; filter: none; } }
button.edit-section svg, a.edit-section svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.show-details > button.edit-section { margin-left: auto; }
/* on phones the details' one is just the pencil, leaving the date room */
@media (max-width: 480px) { .show-details > button.edit-section { padding: 0; } .show-details > button.edit-section span { display: none; } }
/* a link that's a quiet button, e.g. "Drucken" */
a.button.quiet { --raise: transparent; padding: 0 var(--space-2); background: none; border: 0; box-shadow: none; color: var(--fg); }
@media (hover: hover) { a.button.quiet:hover { text-decoration: underline; filter: none; } }
/* what an event is, above its billing: a small word in its colour */
.details-kind { margin: 0 0 var(--space-1); font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--green); }
.details-kind.kind-other { color: var(--gold); }
.details-kind.kind-show { color: var(--kind-show); }
.details-kind .sticker { margin-left: var(--space-2); letter-spacing: normal; text-transform: none; }
.edit-actions { margin-top: var(--space-3); }
.people-edit select { margin-top: var(--space-3); }
.edit-actions .push-right { margin-left: auto; }
.item-details-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-3); }
.image-library { margin-top: var(--space-3); }
.show-thumbnail.placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.6rem;
  background: var(--card);
  border: 1px solid var(--border);
}
/* the poster in the show forms: whole, never cropped, like on its page and
   ticket; without one, no stand-in, just "Bild ändern" */
.show-thumbnail.large { width: auto; height: auto; max-width: 10rem; max-height: 7.5rem; border-radius: var(--radius-m); object-fit: contain; }
.show-thumbnail.large.placeholder { display: none; }

/* choosing a show's poster from the image library (show-edit.html) */
.show-image { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); margin: var(--space-3) 0; }
button.small, a.button.small { padding: 0.2rem var(--space-2); font-size: var(--text-s); }
.image-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.image-tile { display: flex; flex-direction: column; gap: var(--space-1); }
.image-tile > button.secondary { padding: 0.2rem var(--space-2); font-size: var(--text-s); }
button.image-choice {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1);
  background: transparent;
  color: inherit;
  border: 2px solid var(--border);
  border-radius: var(--radius-m);
  font-size: var(--text-s);
}
button.image-choice img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--radius-m); }
button.image-choice span { text-align: center; overflow-wrap: anywhere; }
button.image-choice[aria-pressed="true"] { border-color: var(--fg); box-shadow: 0 0 0 1px var(--fg); }
.image-picker-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }

.attendance-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
/* Who plays, who was there, who said yes or no: a cast list as in a
   programme, names in a line with a dot between them, not pills */
#event-people, .response-lists .attendance-list { display: block; font-size: var(--text-l); line-height: 1.6; }
#event-people .attendance-chip, .response-lists .attendance-chip { display: inline; padding: 0; border: 0; border-radius: 0; font-size: inherit; }
#event-people .attendance-chip + .attendance-chip::before, .response-lists .attendance-chip + .attendance-chip::before { content: ' · '; color: var(--muted); }
#event-people .tag, .response-lists .muted { font-size: var(--text-s); }
#event-people .tag { margin-left: var(--space-1); vertical-align: 0.1em; }
/* a show's cast with what each said: ✓ in the yes green, ✕ in grey */
.cast-said { margin-left: 0.2em; font-size: var(--text-s); font-weight: 700; }
/* a note after a name, in brackets (castNote()): regular weight, even after a bold mark */
.cast-note { font-weight: 400; }
.cast-said-yes { color: var(--green); }
.cast-said-no { color: var(--muted); }
.cast-said .muted { font-weight: normal; }
.cast-answer { margin-bottom: var(--space-3); }
.cast-summary { margin: var(--space-2) 0 0; font-size: var(--text-s); }
/* the counts above a show's cast: in the text colour, so they're read first */
.cast-tally { margin: var(--space-3) 0 var(--space-2); font-size: var(--text-s); font-weight: 600; }
.cast-no { margin: var(--space-2) 0 0; font-size: var(--text-s); }
.cast-label { color: var(--muted); }
.attendance-chip {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 0.2rem var(--space-3) 0.2rem var(--space-2);
  font-size: var(--text-s);
}

.item-notes { margin-top: var(--space-2); }
/* notes grow with what's written, so a long one needn't be scrolled in a
   few lines (on phones especially) */
.item-notes textarea, #show-notes, #training-notes { min-height: 7.5em; field-sizing: content; }

.item-header { display: flex; align-items: center; gap: var(--space-2); }
.item-order-controls { display: flex; flex-direction: column; }
.item-order-controls button { padding: 0 var(--space-1); font-size: var(--text-xs); line-height: 1.4; }

.empty { color: var(--muted); font-style: italic; }

#toast-container {
  position: fixed;
  bottom: var(--space-5);
  right: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  z-index: 1000;
}
.toast {
  background: var(--fg);
  color: var(--bg);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-m);
  font-size: var(--text-s);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.2s ease, transform 0.2s ease;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}
.toast.show {
  opacity: 1;
  transform: translateY(0);
}
.toast { display: flex; align-items: center; gap: var(--space-3); }
/* "Rückgängig" in a toast: a word in the toast's colours, a finger high */
button.toast-action { min-height: var(--tap); margin: calc(-1 * var(--space-2)) calc(-1 * var(--space-3)) calc(-1 * var(--space-2)) auto; padding: 0 var(--space-3); background: none; border: 0; box-shadow: none; color: inherit; font-weight: 700; text-decoration: underline; }
/* on phones a toast is at the top, out of the thumb's way and off the
   answer switches */
@media (max-width: 480px) { #toast-container { top: max(env(safe-area-inset-top, 0px), var(--space-3)); bottom: auto; left: var(--space-3); right: var(--space-3); } }
.toast-error {
  background: var(--danger);
  color: var(--danger-fg);
}

/* Repertoire list: one line of the explanation, none on phones, so the
   list stays short enough to scroll through */
.description-preview {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
/* Repertoire: the initials to jump to, kept in view while scrolling */
.letter-bar {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem;
  margin: 0 -0.25rem var(--space-3);
  padding: var(--space-1) 0;
  background: var(--bg);
}
.letter-bar a {
  color: var(--fg); /* a way around the page, not the next step: --fg */
  display: inline-grid;
  place-items: center;
  min-width: 2.25rem;
  min-height: var(--tap);
  padding: 0;
  text-align: center;
  text-decoration: none;
  font-weight: 600;
  font-size: var(--text-s);
  border-radius: var(--radius-m);
}
.letter-bar a:focus-visible { background: var(--card); }
@media (hover: hover) { .letter-bar a:hover { background: var(--card); } }
#items .card[data-letter] { scroll-margin-top: 3.5rem; } /* not under the letter bar */
/* on phones the letters scroll sideways in one line, rather than a sticky
   bar of two */
@media (max-width: 480px) { .letter-bar { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; } .letter-bar a { flex-shrink: 0; } }
#items .row > div { min-width: 0; } /* lets the line end in … instead of widening the card */
/* the entries as a list with rules, like the setlist; the name's link covers
   the row, the category is a word, not a pill */
#items { border-top: 2px solid var(--fg); }
#items > .card { position: relative; margin: 0; padding: var(--space-3); background: none; border: 0; border-bottom: 1px solid var(--border); border-radius: 0; }
#items > .card a { color: var(--fg); text-decoration: none; font-size: var(--text-l); margin-right: var(--space-2); }
#items > .card a::after { content: ''; position: absolute; inset: 0; }
@media (hover: hover) { #items > .card a:hover { text-decoration: underline; text-decoration-color: var(--accent); text-decoration-thickness: 2px; } }
#items > .card .tag { padding: 0; border: 0; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
#items > .card .description-preview { margin-top: var(--space-1); }
@media (hover: hover) { #items > .card:hover { background: var(--card); } }
@media (max-width: 480px) { .description-preview { display: none; } }

a { color: var(--accent); } /* links in running text; a link standing on its own is --fg (design system, "How much colour") */
.section-head > a:not(.button), .page-header > a:not(.button), .activity-toggle a, .details-tickets a { color: var(--fg); }

.month-heading { font-size: var(--text-s); margin: var(--space-5) 0 var(--space-2); }
.event-when { margin-top: var(--space-1); }
.event-description { margin: var(--space-2) 0 0; font-size: var(--text-s); white-space: pre-line; }

/* Feedback, Aktivität, the troupe on Verwaltung: ruled lists, not boxes */
#feedback-list, .activity-list, .people-list { border-top: 2px solid var(--fg); }
#feedback-list > .card, .activity-list > .card, .people-list > details.card { margin: 0; padding: var(--space-4) var(--space-3); background: none; border: 0; border-bottom: 1px solid var(--border); border-radius: 0; }
#feedback-list .feedback-message { font-size: var(--text-l); }
#feedback-list .feedback-actions { margin-top: var(--space-2); }
#feedback-list .feedback-reply .link-actions { margin: var(--space-1) 0 0 calc(-1 * var(--space-2)); }
/* "Antworten" leads the row of actions, its word lined up with the text above */
#feedback-list .feedback-actions .reply-button:first-child { margin-left: calc(-1 * var(--space-2)); }
.activity-list > .card.activity-entry.new { padding-left: var(--space-3); border-left: 3px solid var(--accent); }
.people-list > details.card > summary { min-height: var(--tap); }
.people-list > details.card[open] { padding-bottom: var(--space-5); }
.feedback-meta { display: flex; gap: var(--space-2); align-items: center; margin-bottom: var(--space-1); }
.feedback-message { margin: 0; white-space: pre-line; }
.feedback-actions { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; margin-top: var(--space-3); }
.feedback-actions .entry-tools { margin-left: auto; display: flex; gap: var(--space-2); } /* Bearbeiten/Löschen on the right */
.feedback-reply { margin-top: var(--space-3); padding: var(--space-1) 0 var(--space-1) var(--space-4); border-left: 1px solid var(--line); } /* an answer indented behind a thin line, as in print, not a box */
.feedback-reply .feedback-message { margin-top: var(--space-1); }
.reply-form { margin-top: var(--space-3); }
button.vote { background: transparent; color: var(--muted); border: 1px solid var(--line); border-radius: var(--radius-pill); padding: 0.2rem var(--space-3); }
/* voted is "chosen", like a chosen chip: green is for trainings and ✓ marks */
button.vote.voted { background: var(--fg); color: var(--bg); border-color: var(--fg); }

.filter-bar { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-4); }
.filter-chip {
  min-height: var(--tap);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  color: var(--fg);
  text-decoration: none;
  font-size: var(--text-s);
}
@media (hover: hover) { .filter-chip:hover { border-color: var(--accent); } }
/* Under every "Ort" field: the places we use most, one tap each
   (public/place-picker.js); the one in the field is filled */
.place-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-1); }
button.place-chip { min-height: var(--tap); padding: var(--space-1) var(--space-3); border: 1px solid var(--line); border-radius: var(--radius-pill); background: none; color: var(--fg); font-size: var(--text-s); text-align: left; }
@media (hover: hover) { button.place-chip:hover { border-color: var(--accent); filter: none; } }
/* a chosen chip is solid --fg like every chosen state; magenta is only for
   what you can tap (docs/design-system.md) */
button.place-chip[aria-pressed="true"] { background: var(--fg); border-color: var(--fg); color: var(--bg); }
.filter-chip.active { background: var(--fg); border-color: var(--fg); color: var(--bg); }
.filter-count { font-size: var(--text-xs); opacity: 0.7; }

.site-footer {
  max-width: 48rem;  /* a readable column: wider screens get margins, not longer lines */
  margin: 0 auto;
  padding: var(--space-5) var(--space-5) var(--space-6);
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-size: var(--text-s);
  text-align: center;
}
.site-footer a { white-space: nowrap; color: var(--muted); } /* the footer is the quietest part of a page */
.changelog-list { margin: 0; padding-left: var(--space-4); }
/* "Was ist neu?": each day under a rule, not in a box; older days folded */
.changelog-day { padding: var(--space-3) 0 var(--space-4); border-top: 2px solid var(--fg); }
.changelog-older { margin-top: var(--space-5); }
.changelog-older > summary { min-height: var(--tap); display: list-item; padding: var(--space-2) 0; cursor: pointer; font-weight: 600; color: var(--fg); }
.changelog-list li + li { margin-top: var(--space-2); }
.changelog-group { font-size: var(--text-s); text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); margin: 0 0 var(--space-2); }
.changelog-list + .changelog-group, .changelog-list + .changelog-minor { margin-top: var(--space-4); }
.changelog-group.changelog-new { color: var(--fg); }
.changelog-minor > summary { cursor: pointer; color: var(--muted); font-size: var(--text-s); }
.changelog-minor > .changelog-list { margin-top: var(--space-2); }

/* Small spacing helpers (instead of inline style attributes, which the
   content security policy blocks) */
.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }
/* Mein Konto's links to the pages that aren't in the menu: Verwaltung
   (admins), Instagram, Assistenten und API-Tokens. The whole row is the
   link, a finger high, not just its words */
.mt-s { margin-top: var(--space-2); }
.mt-m { margin-top: var(--space-3); }
.row.gap-s { gap: var(--space-1); }

/* Icons in the menu */
/* Mein Konto: Automatisch / Hell / Dunkel and the language, one of three:
   a switch like the others (.segmented), the chosen one filled */
.theme-choice { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; max-width: 30rem; border: 1.5px solid var(--muted); border-radius: var(--radius-m); overflow: hidden; background: var(--card); }
.theme-choice button.seg-option { min-height: var(--tap); padding: 0 var(--space-2); border: 0; border-radius: 0; box-shadow: none; background: none; color: var(--fg); white-space: nowrap; }
.theme-choice button.seg-option + button.seg-option { border-left: 1.5px solid var(--muted); }
.theme-choice button.seg-option[aria-pressed='true'] { background: var(--fg); color: var(--bg); }
/* each option its sign over its word (pages/ui.js themeChoice) */
.theme-choice:has(svg) { grid-auto-columns: minmax(0, 1fr); }
.theme-choice button.seg-option:has(svg) { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; min-height: 3.5rem; padding: var(--space-1) 2px; font-size: var(--text-xs); line-height: 1.1; }
.theme-choice svg { width: 22px; height: 22px; flex-shrink: 0; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
/* under the mouse --wash, as every option inside a box (the switch is one) */
@media (hover: hover) { .theme-choice button.seg-option:not([aria-pressed='true']):hover, .answer-choice button.seg-option:not([aria-pressed='true']):hover { background: var(--wash); filter: none; } }
@media (max-width: 480px) { .theme-choice button.seg-option:not(:has(svg)) { font-size: var(--text-s); } }
/* the account page: sections on the paper, devices as a ruled list */
main.account .card { margin: 0; padding: var(--space-2) 0; background: none; border: 0; border-radius: 0; }
main.account #devices { border-top: 2px solid var(--fg); }
main.account #devices > .card { padding: var(--space-3); border-bottom: 1px solid var(--border); }
main.account #devices + .card { padding: var(--space-3); }
/* a page about one's own account (Assistenten und API-Tokens): the whole row is the link */
main.account .home-todo > li { padding: 0; }
main.account .home-todo a { display: flex; align-items: center; min-height: var(--tap); padding: var(--space-2) var(--space-3); }
main.account .home-todo a::after { margin-left: 0.3em; }


/* Login, the first page new people see: a poster (the logo big, the name in
   the display face), then the two ways in as ruled sections, not boxes */
/* the poster is the page's head: no header above it */
body:has(main.login) > header { display: none; }
.poster { display: flex; align-items: center; gap: var(--space-4); margin: var(--space-5) 0 var(--space-2); }
.poster-line { margin: 0 0 var(--space-6); font-family: var(--display); font-size: var(--display-m); letter-spacing: 0.02em; text-transform: uppercase; color: var(--fg); }
.poster img { width: 69px; height: 120px; }
.poster-name { font-family: var(--display); font-size: clamp(3rem, 14vw, 5rem); line-height: 0.9; text-transform: uppercase; color: var(--brand); }
main.login > .card { margin: 0; padding: var(--space-4) 0; background: none; border: 0; border-top: 1px solid var(--border); border-radius: 0; }
main.login > .page-title + .card { border-top: 2px solid var(--fg); }
/* Login by email (login page, Mein Konto): the field and its button on one line where they fit */
.email-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-3); margin-top: var(--space-4); }
.email-form label { display: flex; flex-direction: column; gap: var(--space-1); flex: 1 1 16rem; min-width: 0; }
.email-form .full { flex-basis: 100%; }
/* the stored address, with "Ändern" and "Entfernen" below it where it's too long for one line */
.email-set { flex-wrap: wrap; row-gap: 0; }
.email-address { overflow-wrap: anywhere; }
.email-form .code-input { font-family: ui-monospace, Menlo, monospace; font-size: 1.5rem; letter-spacing: 0.2em; }
/* Login: pairing a new device */
.pairing { display: flex; gap: var(--space-4); align-items: center; flex-wrap: wrap; margin-top: var(--space-4); }
.pair-qr { width: 200px; height: 200px; padding: 8px; background: #ffffff; border-radius: var(--radius-m); }
.pair-code {
  font-family: ui-monospace, Menlo, monospace;
  font-size: 2rem;
  letter-spacing: 0.15em;
  color: var(--fg);
  margin: var(--space-2) 0;
}
.pair-entry input { max-width: 12rem; font-family: ui-monospace, Menlo, monospace; text-transform: uppercase; }

/* Verwaltung (admin page) */
details.person > summary { cursor: pointer; list-style: none; display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
details.person > summary::-webkit-details-marker { display: none; }
details.person > summary::after { content: '▸'; color: var(--muted); }
details.person[open] > summary::after { content: '▾'; }
.person-name { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.person-name .tag { text-transform: none; }
.person-edit { margin-top: var(--space-4); padding-top: var(--space-4); border-top: 1px solid var(--border); }
.person-actions, .link-actions { flex-wrap: wrap; justify-content: flex-start; margin: var(--space-3) 0; }
label.checkbox { display: flex; align-items: center; gap: var(--space-2); min-height: var(--tap); } /* the whole line a finger high */
/* checkboxes one under the other, far enough apart to tap (Mein Konto) */
.check-list { display: grid; gap: var(--space-1); }
/* several lines: the box beside the first */
.check-list label.checkbox { align-items: flex-start; padding: var(--space-2) 0; }
.check-list input { margin-top: 0.1rem; }
.form-grid label { display: flex; flex-direction: column; gap: var(--space-1); font-size: var(--text-s); color: var(--muted); }
.link-box { margin-top: var(--space-4); padding: var(--space-3) var(--space-4); border: 1px dashed var(--line); border-radius: var(--radius-m); }
.link-box input { font-family: ui-monospace, Menlo, monospace; font-size: var(--text-s); }
button.danger { --raise: color-mix(in srgb, var(--danger) 55%, #000); background: var(--danger); color: var(--danger-fg); }

/* A link that looks like a button (e.g. "+ Neue Show"): see the buttons above */
.edit-actions { justify-content: flex-start; flex-wrap: wrap; }
/* Formatted text (markdown.js): explanations, show descriptions, notes */
.formatted { white-space: normal; overflow-wrap: anywhere; }
.formatted > :first-child { margin-top: 0; }
.formatted > :last-child { margin-bottom: 0; }
.formatted p { margin: 0 0 0.75em; }
.formatted ul, .formatted ol { margin: 0 0 0.75em; padding-left: 1.4em; }
.formatted li > ul, .formatted li > ol { margin: 0.15em 0 0.15em; }
.formatted li + li { margin-top: 0.2em; }
.formatted h3, .formatted h4 { margin: 1.1em 0 0.4em; font-family: inherit; letter-spacing: normal; text-transform: none; }
.formatted h3 { font-size: 1.1em; }
.formatted h4 { font-size: 1em; }

/* Its editor (text-editor.js): a toolbar above the field, a preview instead */
.text-editor { display: flex; flex-direction: column; gap: var(--space-1); }
.fmt-toolbar { display: flex; flex-wrap: wrap; gap: var(--space-1); }
button.fmt-button { padding: 0.15rem var(--space-2); min-width: 2rem; font-size: var(--text-s); line-height: 1.4; }
button.fmt-list { font-size: var(--text-l); line-height: 1.1; }
button.fmt-button:disabled { opacity: 0.4; cursor: default; }
button.fmt-bold { font-weight: 700; }
button.fmt-italic { font-style: italic; font-family: Georgia, serif; }
button.fmt-preview { margin-left: auto; }
button.fmt-preview[aria-pressed='true'] { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.text-preview { min-height: 3.5em; padding: var(--space-2) var(--space-2); border: 1px dashed var(--border); border-radius: var(--radius-m); }
.card.item-header { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
/* Notes per running-order entry on the show and training pages */
.entry-head { gap: var(--space-2); flex-wrap: wrap; }
.entry-notes { margin-top: var(--space-2); color: var(--muted); font-size: var(--text-s); }
/* A setlist (pages/running-order.js; docs/design-system.md): a running order
   like a printed programme, the numbers set big in the display face, a rule
   between entries, the whole row opening the entry */
.setlist { list-style: none; margin: 0; padding: 0; border-top: 2px solid var(--fg); }
.setlist > li { border-bottom: 1px solid var(--border); }
.setlist-entry { position: relative; display: flex; align-items: baseline; gap: var(--space-3); padding: var(--space-3) 0; }
.setlist-number { flex: 0 0 2.25rem; font-family: var(--display); font-size: 2rem; line-height: 1; color: var(--muted); text-align: right; font-variant-numeric: tabular-nums; }
.setlist-body { flex: 1; min-width: 0; }
.setlist-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-1) var(--space-3); }
.setlist-title { font-size: var(--text-l); font-weight: 700; color: var(--fg); text-decoration: none; overflow-wrap: anywhere; }
a.setlist-title::after { content: ''; position: absolute; inset: 0; }
@media (hover: hover) { a.setlist-title:hover { text-decoration: underline; text-decoration-color: var(--accent); text-decoration-thickness: 2px; } }
.setlist-category { font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.setlist .tip-count, .setlist .entry-notes a { position: relative; z-index: 1; }
/* The running order being changed (public/running-order.js): the same
   setlist, each row with ↑ ↓ ✕ as 44 px tools on the right, notes opened per
   entry, the formatting toolbar only from when a field is written in */
.setlist-entry-edit { align-items: flex-start; }
.setlist-entry-edit .setlist-number { padding-top: var(--space-1); }
.order-tools { display: flex; flex-shrink: 0; margin: calc(-1 * var(--space-1)) calc(-1 * var(--space-2)) 0 0; }
button.order-tool { width: var(--tap); height: var(--tap); padding: 0; font-size: var(--text-l); color: var(--muted); border-radius: var(--radius-m); }
@media (hover: hover) { button.order-tool:hover { background: var(--card); color: var(--fg); } }
.setlist-pause-edit .order-tool { font-family: inherit; letter-spacing: normal; }
.setlist-pause-edit .order-tools { font-family: system-ui, sans-serif; }
.setlist-pause-edit { display: flex; align-items: center; justify-content: space-between; padding-left: var(--space-3); }
button.order-add-note { min-height: var(--tap); margin-left: calc(-1 * var(--space-2)); font-size: var(--text-s); }
.setlist-edit .item-notes { margin-top: var(--space-2); }
.setlist-edit .text-editor.fmt-later .fmt-toolbar { display: none; }
.order-add { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-4); }
.order-add select { flex: 1 1 14rem; width: auto; }
.setlist-pause { padding: var(--space-2) 0; text-align: center; font-family: var(--display); font-size: var(--text-l); letter-spacing: 0.3em; text-transform: uppercase; color: var(--muted); background: repeating-linear-gradient(-45deg, transparent 0 6px, var(--card) 6px 12px); }

/* Show edit page on phones: the picture above the fields */
@media (max-width: 600px) {
  .show-details.show-edit { flex-direction: column; gap: var(--space-3); }
}

/* Page title with the page's main action (Bearbeiten, Fertig) beside it */
.page-header { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; margin: var(--space-2) 0 var(--space-4); }
.page-header .page-title { margin: 0; }
/* a page's actions keep their labels on one line; on a phone they move under the title together */
.page-header > .row { flex-wrap: wrap; }
.page-header > .row > button, .page-header > .row > a.button { white-space: nowrap; }
/* "Trainings › Training am Fr., 13. Nov. 2026" above a title */
.breadcrumb { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: var(--space-3) 0 -0.25rem; font-size: var(--text-s); color: var(--muted); }
.breadcrumb a { color: var(--muted); text-decoration: none; }
@media (hover: hover) { .breadcrumb a:hover { color: var(--fg); text-decoration: underline; text-decoration-color: var(--accent); } }
@media (hover: hover) { .breadcrumb a:hover { text-decoration: underline; } }
#autosave-hint { margin-top: -0.5rem; }

/* Unread replies on the Feedback page: "neu" on the reply */
.tag.new { background: none; color: var(--fg); font-weight: 600; text-transform: none; }

/* Change history (show and repertoire pages) */
details.history > summary { cursor: pointer; font-weight: 600; }
.history-list { list-style: none; padding: 0; margin: var(--space-3) 0 0; }
.history-row { padding: var(--space-2) 0; border-top: 1px solid var(--border); display: grid; gap: var(--space-1); }
.history-row > .history-restore { justify-self: start; margin-top: var(--space-1); }
.history-diff summary { cursor: pointer; color: var(--fg); font-size: var(--text-s); }
.history-versions { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); margin-top: var(--space-2); }
.history-text { margin: 0.2rem 0 0; white-space: pre-line; font-size: var(--text-s); }
@media (max-width: 600px) { .history-versions { grid-template-columns: 1fr; } }

/* Repertoire entry: the shows it was played in */
.played-in { list-style: none; margin: 0; display: grid; gap: var(--space-2); }
.played-in a { color: var(--fg); } /* a list of links, not running text */
/* what it was (SHOW, TRAINING) as a small word in its colour, as on a
   ticket; "geplant" / "heute" after the date as plain text */
.played-in .tag { margin-right: var(--space-2); padding: 0; border: 0; background: none; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.played-in .tag.kind-show, .played-in .tag.kind-training { background: none; }
.played-in .tag.kind-show { color: var(--kind-show); }
.played-in .tag.kind-training { color: var(--green); }
.played-in .muted + .tag { margin-left: var(--space-1); text-transform: none; letter-spacing: normal; font-weight: normal; }

/* Repertoire entry: Do's & Don'ts, side by side on wider screens. A point
   opens on tap to show who added it, with editing and deleting. */
.tip-lists { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.tip-lists > .card { margin: 0; display: flex; flex-direction: column; }
@media (max-width: 600px) { .tip-lists { grid-template-columns: 1fr; } }
.tip-list h3 { margin: 0 0 var(--space-2); font-size: var(--text-m); }
.tip-list .empty { margin: 0 0 var(--space-3); }
.tips { list-style: none; padding: 0; margin: 0 0 var(--space-3); display: grid; gap: var(--space-2); }
.tip > summary { list-style: none; cursor: pointer; display: flex; gap: var(--space-2); overflow-wrap: anywhere; margin: -0.15rem -0.3rem; padding: 0.15rem var(--space-1); border-radius: var(--radius-s); }
.tip > summary::-webkit-details-marker { display: none; }
.tip > summary::before { flex-shrink: 0; font-weight: 700; }
.tip-list-do .tip > summary::before { content: '✓'; color: var(--green); }
.tip-list-dont .tip > summary::before { content: '✕'; color: var(--fg); } /* not the accent: that's for what you can do */
.tip-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: var(--space-1) 0 0.2rem var(--space-5); }
.tip-meta .muted { flex: 1; white-space: nowrap; }
/* its actions as icons, finger-sized; "Wirklich löschen?" replaces the icon
   until confirmed */
button.tip-action { width: var(--tap); height: var(--tap); padding: 0; line-height: 0; border-radius: 50%; }
button.tip-action svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
@media (hover: hover) { button.tip-action:hover { background: var(--border); color: var(--fg); opacity: 1; } }
button.tip-action.danger { width: auto; padding: 0.15rem var(--space-2); border-radius: var(--radius-m); font-size: var(--text-s); line-height: normal; }
/* A point reacts to the pointer, so it's clear it opens (only where there's
   a mouse: on phones a hover would stick after the tap) */
@media (hover: hover) { .tip > summary:hover { background: var(--border); } }
.tip[open] > summary { background: var(--border); }
/* Personal marks (issue #32): the star beside each point, outlined or filled
   (shape, not just colour), with a finger-sized target */
.tip-row { display: flex; align-items: flex-start; gap: var(--space-1); }
.tip-row > .tip { flex: 1; min-width: 0; }
button.tip-star {
  background: transparent; color: var(--muted); padding: 0; flex-shrink: 0;
  width: 2.75rem; height: 2.75rem; margin: -0.65rem -0.6rem -0.65rem 0;
  font-size: var(--text-l); line-height: 1; border-radius: 50%;
}
button.tip-star::before { content: '☆'; }
button.tip-star[aria-pressed="true"] { color: var(--fg); }
button.tip-star[aria-pressed="true"]::before { content: '★'; }
@media (hover: hover) { button.tip-star:hover { background: var(--border); opacity: 1; } }
/* Hidden for oneself: folded away below the list, greyed out when shown */
.tips-hidden { margin: 0 0 var(--space-3); }
.tips-hidden > summary { cursor: pointer; color: var(--muted); font-size: var(--text-s); }
@media (hover: hover) { .tips-hidden > summary:hover { color: var(--accent); } }
.tips-hidden .tips { margin: var(--space-2) 0 0; }
.tips-hidden .tip-row { color: var(--muted); align-items: center; }
.tips-hidden .tip > summary::before { color: var(--muted); }
.tips-hidden .tip-star, .tips-hidden [data-tip-hide], .tips-shown .tip-unhide { display: none; }
.tip-unhide { padding: 0.15rem var(--space-2); font-size: var(--text-s); flex-shrink: 0; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.tip-add, .tip-edit { display: flex; gap: var(--space-2); margin-top: auto; }
.tip-edit { flex-wrap: wrap; margin-top: 0; }
.tip-edit textarea { flex: 1 1 100%; min-height: 4.5em; field-sizing: content; }
.tip-edit select { width: auto; }
/* a show's look back (pages/show-points.js): three lists, like the Do's & Don'ts */
.point-lists { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 900px) { .point-lists { grid-template-columns: 1fr; } }
.point-list-good .tip > summary::before { content: '✓'; color: var(--green); }
.point-list-bad .tip > summary::before { content: '↗'; color: var(--fg); } /* room to grow, not a cross: it's constructive; a mark, so not in the accent */
.point-list-neutral .tip > summary::before { content: '•'; color: var(--muted); }
/* its one form above the lists: the switch, the text, what it's on */
.point-add { display: grid; gap: var(--space-2); max-width: 40rem; margin-bottom: var(--space-5); }
.point-add-row { display: flex; gap: var(--space-2); }
.point-add-row select { flex: 1; min-width: 0; }
.point-add-row button { flex-shrink: 0; min-height: var(--tap); }
.point-add input[type=text] { min-height: var(--tap); }
/* the lists as ruled columns, not boxes; also a repertoire entry's Do's &
   Don'ts, its explanation (the billing, as on an event's page) and where it
   was played */
div.card.item-details { padding: var(--space-4) 0; background: none; border: 0; border-top: 2px solid var(--fg); border-bottom: 1px solid var(--border); border-radius: 0; }
ul.card.played-in { padding: 0; background: none; border: 0; border-radius: 0; }
.played-in > li { padding: var(--space-2) 0; border-bottom: 1px solid var(--border); }
/* the change history at the bottom of a page: a ruled line that opens */
details.card.history { padding: var(--space-3) 0; background: none; border: 0; border-top: 2px solid var(--fg); border-bottom: 1px solid var(--border); border-radius: 0; }
details.card.history > summary { padding: var(--space-2) 0; } /* a finger high, keeping its ▸ */
.tip-lists > .card, .point-lists > .card { margin: 0; padding: 0; background: none; border: 0; border-radius: 0; }
/* one heavy rule over the lists, not one per group */
.tip-lists, .point-lists { padding-top: var(--space-3); border-top: 2px solid var(--fg); }
.tip-add { margin-bottom: var(--space-4); }
.point-lists h3 { font-family: var(--display); font-weight: normal; font-size: var(--text-l); letter-spacing: 0.05em; text-transform: uppercase; }
.point-lists, .tip-lists { gap: var(--space-4); }
.point-lists .tip-meta { flex-wrap: nowrap; }
.point-lists .tip-meta .muted { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* in a running order: how many an entry has, linking to them */
.tip-count { display: inline-flex; align-items: center; min-height: var(--tap); font-size: var(--text-s); color: var(--muted); }
/* under the mouse darker, its underline in the accent, as the other links in a list */
@media (hover: hover) { .tip-count:hover { color: var(--fg); text-decoration-color: var(--accent); } }

/* Trainings: people to switch on and off (leaders, attendance) */
/* in an event's editor they're a line of names too (docs/design-system.md):
   a chosen name bold with ✓, the others muted, each a finger high */
form .toggle-list { gap: 0 var(--space-1); }
form .toggle-list button.toggle-chip { min-height: var(--tap); padding: 0 var(--space-2); border: 0; background: none; color: var(--muted); font-size: var(--text-l); }
form .toggle-list button.toggle-chip.on { background: none; color: var(--fg); font-weight: 700; }
form .toggle-list button.toggle-chip.on::before { content: '✓ ' / ''; color: var(--green); }
@media (hover: hover) { form .toggle-list button.toggle-chip:hover { background: var(--card); opacity: 1; } }
/* answers for others (admins): a row per member, name, ✓ ✕ – and a note */
.answer-rows { list-style: none; margin: 0 0 var(--space-3); padding: 0; }
.answer-row { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: var(--space-2) var(--space-3); padding: var(--space-2) 0; border-bottom: 1px solid var(--border); }
.answer-name { font-size: var(--text-l); font-weight: 600; overflow-wrap: anywhere; }
.segmented.answer-choice { grid-auto-columns: var(--tap); }
.answer-choice button.seg-option { min-height: var(--tap); padding: 0; border: 0; border-radius: 0; box-shadow: none; background: none; color: var(--fg); font-weight: 700; }
.answer-choice button.seg-option + button.seg-option { border-left: 1.5px solid var(--muted); }
.answer-choice button.seg-option[aria-pressed='true'] { background: var(--fg); color: var(--bg); }
.answer-note, button.answer-add-note { grid-column: 1 / -1; }
button.answer-add-note { justify-self: start; min-height: var(--tap); margin: calc(-1 * var(--space-2)) 0 0 calc(-1 * var(--space-2)); font-size: var(--text-s); }
.answer-guests { margin-top: var(--space-3); }
.card.people-edit, .card.leaders-edit { padding: var(--space-3) 0 0; background: none; border: 0; border-top: 2px solid var(--fg); border-radius: 0; }
.toggle-list { display: flex; flex-wrap: wrap; gap: var(--space-2); }
button.toggle-chip { background: transparent; color: var(--muted); border: 1px solid var(--line); border-radius: var(--radius-pill); padding: var(--space-1) var(--space-3); }
button.toggle-chip.on { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.event-tags { display: flex; gap: var(--space-1); flex-wrap: wrap; justify-content: flex-end; }
.card.cancelled { opacity: 0.6; }

/* Termine: month calendar */
.calendar-nav { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-3); }
.calendar-nav h2 { margin: 0; min-width: 10.5rem; text-align: center; }
.calendar-nav a.icon { display: inline-grid; place-items: center; width: var(--tap); height: var(--tap); font-size: 1.6rem; line-height: 1; color: var(--muted); text-decoration: none; }
@media (hover: hover) { .calendar-nav a.icon:hover { opacity: 0.85; } }
/* the grid like a printed calendar (docs/design-system.md): no boxes, a
   heavy rule on top and thin ones between the weeks, the days in the display
   face, today's on a disc in the text colour (not a kind's colour) */
.calendar { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); margin-bottom: var(--space-5); border-top: 2px solid var(--fg); }
.cal-weekday { text-align: center; font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); padding: var(--space-2) 0; border-bottom: 1px solid var(--border); }
.cal-day { min-height: 4.2rem; padding: var(--space-1) 2px; display: flex; flex-direction: column; gap: 2px; min-width: 0; border-bottom: 1px solid var(--border); }
.cal-number { align-self: center; display: grid; place-items: center; min-width: 1.75rem; height: 1.75rem; border-radius: var(--radius-pill); font-family: var(--display); font-size: var(--text-l); line-height: 1; }
.cal-day.past .cal-number { color: var(--muted); }
.cal-day.today .cal-number { background: var(--fg); color: var(--bg); }
@media (hover: hover) { .cal-day.has-events:hover { background: var(--card); } }
.cal-event { display: block; font-size: var(--text-xs); line-height: 1.3; padding: 0.05rem var(--space-1); border-radius: var(--radius-s); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cal-event.kind-show { background: var(--kind-show); color: var(--accent-fg); }
.cal-event.kind-training { background: var(--green); color: var(--accent-fg); }
.cal-event.kind-other { background: var(--gold); color: var(--accent-fg); }
.cal-event.cancelled { text-decoration: line-through; opacity: 0.6; }
/* an event over several days is one bar (pages/events.js, weekLanes): its
   pieces reach the edge of their day where it goes on, without the round
   corner there, and keep their line; a free line on a day is a gap */
.cal-event.cont-left { margin-left: -2px; border-top-left-radius: 0; border-bottom-left-radius: 0; }
.cal-event.cont-right { margin-right: -2px; border-top-right-radius: 0; border-bottom-right-radius: 0; }
.cal-gap { visibility: hidden; }
/* its name runs along the bar to the week's (or month's) end, over the
   pieces after it: n days of the piece's width plus the gaps between them */
.cal-event.spans { position: relative; z-index: 1; overflow: visible; }
.cal-label { display: block; overflow: hidden; text-overflow: ellipsis; }
.span-2 .cal-label { width: calc(200% + 4px); }
.span-3 .cal-label { width: calc(300% + 8px); }
.span-4 .cal-label { width: calc(400% + 12px); }
.span-5 .cal-label { width: calc(500% + 16px); }
.span-6 .cal-label { width: calc(600% + 20px); }
.span-7 .cal-label { width: calc(700% + 24px); }
/* a birthday: the cake and the name, no colour (it's no kind of event) */
.cal-birthday { display: block; font-size: var(--text-xs); line-height: 1.3; padding: 0.05rem var(--space-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--muted); }
.birthday-line { margin: 0 0 var(--space-3); padding: var(--space-2) var(--space-3); }
.birthday-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-3); }
.birthday-form label { display: flex; flex-direction: column; gap: var(--space-1); }
.tag.kind-show { background: var(--kind-show); color: var(--accent-fg); }
.tag.kind-other { background: var(--gold-soft); color: var(--gold); border-color: transparent; }
.tag.kind-training { background: var(--green-soft); color: var(--green); border-color: transparent; }
.tag.kind-show { border-color: transparent; }
.event-card.past { opacity: 0.75; }

/* A ticket (Termine, Übersicht; docs/design-system.md): the stub in the
   kind's colour with the date in the display face, a perforation with a notch
   at each end, then the body. The title's link covers the ticket (::after);
   buttons are lifted above it. */
.ticket {
  --kind: var(--kind-show);
  --stub: 3.75rem;
  position: relative;
  display: flex;
  padding: 0;
  border: 0;
  overflow: hidden;
  /* the notches: a bite out of the top and bottom edge at the perforation */
  -webkit-mask: radial-gradient(circle 7px at var(--stub) 0, transparent 98%, #000) top / 100% 51% no-repeat,
                radial-gradient(circle 7px at var(--stub) 100%, transparent 98%, #000) bottom / 100% 51% no-repeat;
  mask: radial-gradient(circle 7px at var(--stub) 0, transparent 98%, #000) top / 100% 51% no-repeat,
        radial-gradient(circle 7px at var(--stub) 100%, transparent 98%, #000) bottom / 100% 51% no-repeat;
}
.ticket.kind-training { --kind: var(--green); }
.ticket.kind-other { --kind: var(--gold); }
.ticket.cancelled { --kind: var(--muted); }
.ticket-stub {
  flex: 0 0 var(--stub);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-1);
  background: var(--kind);
  color: var(--accent-fg);
  border-right: 2px dashed var(--card);
  font-family: var(--display);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  line-height: 1;
  text-align: center;
}
.ticket-weekday, .ticket-month { font-size: var(--text-l); }
.ticket-day { font-size: 2.4rem; }
.ticket-body { flex: 1; min-width: 0; padding: var(--space-3); }
.ticket-eyebrow { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin-bottom: var(--space-1); }
.ticket-kind { font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--kind); }
.ticket-title { display: block; font-size: var(--text-l); font-weight: 700; line-height: 1.25; color: var(--fg); text-decoration: none; overflow-wrap: anywhere; }
.ticket-title::after { content: ''; position: absolute; inset: 0; }
.ticket-title:focus-visible { text-decoration: underline; text-decoration-color: var(--kind); text-decoration-thickness: 2px; }
@media (hover: hover) { .ticket-title:hover { text-decoration: underline; text-decoration-color: var(--kind); text-decoration-thickness: 2px; } }
.ticket-title:focus-visible { outline: none; }
.ticket:has(.ticket-title:focus-visible) { box-shadow: inset 0 0 0 2px var(--accent); } /* the mask would cut a ring outside */
.ticket.cancelled .ticket-title { text-decoration: line-through; }
.ticket button, .ticket input, .ticket a:not(.ticket-title) { position: relative; z-index: 1; }
.ticket .event-when { margin-top: var(--space-1); }
.ticket.flash { box-shadow: inset 0 0 0 2px var(--kind); transition: box-shadow 0.3s; }
/* A sticker: your role, stuck on the ticket's corner ("Du spielst mit",
   "Du leitest"), one at most; so it doesn't push the lines down, and in dark
   mode dark with a light outline rather than a white block (not the accent,
   which is for actions, nor a kind's colour) */
.ticket-body { position: relative; }
.ticket-body > .sticker { position: absolute; top: var(--space-2); right: var(--space-2); transform: rotate(3deg); box-shadow: 0 2px 0 color-mix(in srgb, var(--fg) 25%, transparent); }
.sticker {
  display: inline-block;
  padding: 0.1rem var(--space-2);
  border-radius: var(--radius-s);
  background: var(--fg);
  color: var(--bg);
  font-size: var(--text-xs);
  font-weight: 700;
  white-space: nowrap;
  transform: rotate(-2deg);
}
@media (min-width: 600px) {
  .ticket { --stub: 5rem; }
  .ticket-body { padding: var(--space-3) var(--space-4) var(--space-4); }
  .ticket-day { font-size: 2.8rem; }
}
/* on phones the entries are coloured bars; tapping the day jumps to the list */
@media (max-width: 480px) {
  .cal-day { min-height: 3rem; }
  .cal-event { font-size: 0; height: 0.4rem; padding: 0; pointer-events: none; }
  .cal-birthday { padding: 0; text-align: center; }
  .cal-birthday-name { display: none; }
  .cal-event.kind-training { background: var(--green); }
  .cal-event.kind-other { background: var(--gold); }
}
.cal-day.has-events { cursor: pointer; }
.tag { white-space: nowrap; }
.event-tags { flex-shrink: 0; }
.training-status { margin-top: 0.2rem; font-weight: 600; }

/* Search (page and repertoire filter) */
/* the search field's clearing ×: in the muted colour, not the browser's blue */
input[type=search]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  width: 1.1rem;
  height: 1.1rem;
  background: var(--muted);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 6l12 12M18 6L6 18' stroke='black' stroke-width='2.5' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 6l12 12M18 6L6 18' stroke='black' stroke-width='2.5' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;
  cursor: pointer;
}
input[type=search] { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-m); padding: var(--space-2) var(--space-3); width: 100%; font-size: var(--text-m); }
.search-input { margin-bottom: var(--space-4); }
/* the results as ruled lists, like the repertoire (docs/design-system.md) */
.search-group { border-top: 2px solid var(--fg); }
.search-group .card.search-result { margin: 0; padding: var(--space-3); background: none; border: 0; border-bottom: 1px solid var(--border); border-radius: 0; }
.search-group .show-list-item { color: var(--fg); }
.search-group .search-result strong { font-size: var(--text-l); }
.search-group .search-result .tag { padding: 0; border: 0; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
@media (hover: hover) { .search-group .show-list-item:hover .search-result { background: var(--card); } .search-group .show-list-item:hover strong { text-decoration: underline; text-decoration-color: var(--accent); text-decoration-thickness: 2px; } }
.search-result .item-header { flex-wrap: wrap; }
.search-snippet { margin: var(--space-1) 0 0; }
mark { background: var(--highlight); color: #3a1a2b; border-radius: var(--radius-s); padding: 0 1px; }

/* Setup guide (assistant.html) */
ol.steps li { margin-bottom: var(--space-2); }
#mcp-url { font-family: ui-monospace, Menlo, monospace; }

/* Assistant chat (chat.html, issue #22) */
.chat-log { display: flex; flex-direction: column; gap: var(--space-3); margin: var(--space-4) 0; }
.chat-message { max-width: 85%; padding: var(--space-2) var(--space-4); border-radius: var(--radius-l); overflow-wrap: anywhere; }
.chat-message.user { align-self: flex-end; background: var(--fg); color: var(--bg); white-space: pre-line; border-bottom-right-radius: 4px; }
.chat-message.assistant { align-self: flex-start; background: var(--card); border: 1px solid var(--border); border-bottom-left-radius: 4px; }
.chat-message .formatted > :first-child { margin-top: 0; }
.chat-message .formatted > :last-child { margin-bottom: 0; }
.chat-files { font-size: var(--text-s); opacity: 0.85; margin-bottom: var(--space-1); }
.chat-activity { margin: var(--space-1) 0 0; color: var(--muted); font-size: var(--text-s); font-style: italic; }
.chat-error { margin: var(--space-2) 0 0; color: var(--danger); font-weight: 600; }
.chat-composer .attendance-list:empty { display: none; }
/* how many messages are left today, right under "Senden"; bolder near the end */
.chat-usage { margin: var(--space-2) 0 0; text-align: right; font-size: var(--text-s); color: var(--muted); }
.chat-usage.low { color: var(--fg); font-weight: 600; }
.chat-composer .attendance-list { margin-bottom: var(--space-2); }
/* removing an attachment: a finger-sized target around the small ✕ */
.chat-composer .attendance-chip button.icon { min-width: var(--tap); min-height: var(--tap); margin: calc(-1 * var(--space-2)) calc(-1 * var(--space-2)) calc(-1 * var(--space-2)) 0; padding: 0; }
/* "Frühere Chats": a ruled list, like Aktivität and Feedback */
.chat-history-list { border-top: 2px solid var(--fg); }
.chat-history-item { gap: var(--space-3); padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--border); flex-wrap: nowrap; }
.chat-history-item a { display: grid; gap: 0.1rem; min-width: 0; overflow-wrap: anywhere; text-decoration: none; }
.chat-history-item .muted { font-size: var(--text-s); }
.chat-history-item button { flex-shrink: 0; }
.proposal-card { border-color: var(--line); }
.proposal-title { font-weight: 600; }
.proposal-list { margin: var(--space-2) 0; padding: 0; list-style: none; display: grid; gap: var(--space-2); }
.proposal-choice { display: flex; align-items: flex-start; gap: var(--space-2); cursor: pointer; }
.proposal-choice input { margin-top: var(--space-1); width: 1.1rem; height: 1.1rem; flex-shrink: 0; accent-color: var(--fg); }
.proposal-group-title { font-weight: 600; font-size: var(--text-s); }
.proposal-group > .proposal-list { margin: var(--space-1) 0 0; }
.proposal-list li.left-out > .proposal-choice > span { opacity: 0.5; }
.proposal-hint { color: var(--muted); font-size: var(--text-s); font-style: italic; }
.proposal-list .tag { margin-left: var(--space-2); }
.proposal-detail { color: var(--muted); font-size: var(--text-s); white-space: pre-line; margin-top: 0.15rem; }
.proposal-status { font-size: var(--text-s); font-weight: 600; }
.proposal-status.ok { color: var(--green); }
.proposal-status.failed { color: var(--danger); }
@media (max-width: 480px) { .chat-message { max-width: 95%; } }

/* Termine: "Kalender abonnieren" opens a panel below the page title */
.page-header:has(.subscribe) { position: relative; }
details.subscribe > summary { list-style: none; }
details.subscribe > summary::-webkit-details-marker { display: none; }
.subscribe-panel {
  position: absolute;
  z-index: 10;
  top: 100%;
  right: 0;
  width: min(30rem, 100%);
  margin-top: var(--space-2);
  background: var(--card);
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.15);
}
.subscribe-panel > p:first-child { margin-top: 0; }
.subscribe-panel > p:last-child { margin-bottom: 0; }
.subscribe-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
  background: var(--card);
  color: inherit;
  text-decoration: none;
}
@media (hover: hover) { .subscribe-option:hover { border-color: var(--accent); } }
.subscribe-option strong, .subscribe-option small { display: block; }
.subscribe-option .go { color: var(--fg); white-space: nowrap; font-weight: 600; }
/* "+ Neu" on Termine: the same kind of panel, narrower, its options without
   an arrow; the summary looks like the main button */
details.new-menu[open] > summary, details.subscribe[open] > summary { transform: translateY(2px); box-shadow: 0 1px 0 var(--raise); }
/* hangs below "+ Neu" itself, not from the page's right edge */
details.new-menu { position: relative; }
/* "+ Neu ▾": a choice, not a form; the caret turns up while it's open */
.menu-caret { width: 16px; height: 16px; margin-right: calc(-1 * var(--space-1)); fill: none; stroke: currentColor; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; transition: transform 0.15s ease; }
details[open] > summary .menu-caret { transform: rotate(180deg); }
/* "+ Neu" usually sits at the right edge: open towards the page, never off
   screen. A set width, capped at the screen. */
.new-menu-panel { width: 15rem; max-width: calc(100vw - 2 * var(--space-3)); left: auto; right: 0; }
/* … unless "+ Neu" has wrapped to the left edge (public/new-menu.js) */
.new-menu-panel.to-right { left: 0; right: auto; }
.new-menu-panel .subscribe-option:last-child { margin-bottom: 0; }
.new-menu-panel .subscribe-option { justify-content: flex-start; gap: var(--space-3); }
/* "+ Neu" as a ruled list in its panel, not three boxes */
.new-menu-panel .subscribe-option { margin: 0; min-height: var(--tap); padding: var(--space-2) var(--space-3); border: 0; border-bottom: 1px solid var(--border); border-radius: 0; background: none; }
.new-menu-panel .subscribe-option:last-child { border-bottom: 0; }
/* under the mouse --wash: the panel is a card, so the rows' usual --card
   background wouldn't show, and the subscribe options' pink border is gone
   here */
@media (hover: hover) { .new-menu-panel .subscribe-option:hover { background: var(--wash); } }
.new-menu-panel { padding: var(--space-1) 0; }
/* each kind's icon on a round patch in its calendar colour */
.new-icon { flex-shrink: 0; display: grid; place-items: center; width: 2.25rem; height: 2.25rem; border-radius: 50%; line-height: 0; }
.new-icon svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.new-icon.kind-show { background: var(--kind-show); color: var(--accent-fg); }
.new-icon.kind-training { background: var(--green-soft); color: var(--green); }
.new-icon.kind-other { background: var(--gold-soft); color: var(--gold); }
.copy-row { display: flex; gap: var(--space-2); }
.copy-row input { flex: 1; min-width: 0; font-family: ui-monospace, Menlo, monospace; font-size: var(--text-s); }
/* "Im eigenen Kalender? Abonnieren →" on Termine: one does it once, so no
   button but a small line at the right under the calendar, like a caption;
   its panel opens in place below it instead of dropping over the page */
details.subscribe-inline { margin: calc(-1 * var(--space-3)) 0 var(--space-5); }
details.subscribe.subscribe-inline > summary,
details.subscribe.subscribe-inline[open] > summary { display: flex; flex-wrap: wrap; justify-content: flex-end; width: fit-content; max-width: 100%; margin-left: auto; gap: 0 0.4em; padding: 0; background: none; border: 0; box-shadow: none; transform: none; color: var(--fg); font-size: var(--text-s); font-weight: 600; text-align: right; }
.subscribe-lead { color: var(--muted); font-weight: normal; }
@media (hover: hover) { details.subscribe.subscribe-inline > summary:hover { filter: none; text-decoration: underline; text-decoration-color: var(--accent); } }
details.subscribe-inline > .subscribe-panel { position: static; width: auto; max-width: 30rem; margin: var(--space-1) 0 0 auto; box-shadow: none; border: 1px solid var(--border); }
details.subscribe-help { margin: var(--space-3) 0; }
details.subscribe-help > summary { cursor: pointer; color: var(--fg); font-size: var(--text-s); }
details.subscribe-help p { font-size: var(--text-s); margin: var(--space-2) 0 0; }

/* Instagram (issue #30): numbers as tiles, charts as SVG (marks only, in a
   stretched 100×100 box) with their labels in HTML, and the latest posts */
.ig-error { color: var(--danger); font-weight: 600; }
.ig-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-2); margin: var(--space-4) 0 var(--space-2); }
@media (max-width: 600px) { .ig-tiles { grid-template-columns: 1fr 1fr; } }
.ig-tile { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-m); padding: var(--space-3) var(--space-4); }
.ig-tile-label { color: var(--muted); font-size: var(--text-s); }
.ig-tile-value { font-family: var(--display); font-size: 2.2rem; line-height: 1.1; }
.ig-tile-note { color: var(--muted); font-size: var(--text-s); }
.ig-chart { margin: 0 0 var(--space-3); }
.ig-chart svg { display: block; width: 100%; height: 160px; overflow: visible; }
.ig-axis-top { color: var(--muted); font-size: var(--text-xs); margin-bottom: var(--space-1); }
.ig-axis-x { display: flex; justify-content: space-between; color: var(--muted); font-size: var(--text-xs); margin-top: var(--space-1); }
.ig-grid { stroke: var(--border); stroke-width: 1; stroke-dasharray: 3 3; }
.ig-baseline { stroke: var(--muted); stroke-width: 1; }
.ig-bar { fill: var(--fg); }
@media (hover: hover) { .ig-bar:hover { opacity: 0.8; } }
.ig-line { fill: none; stroke: var(--fg); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.ig-table { margin-top: var(--space-2); font-size: var(--text-s); }
.ig-table > summary { cursor: pointer; color: var(--muted); }
.ig-table table { border-collapse: collapse; margin-top: var(--space-2); }
.ig-table th, .ig-table td { text-align: left; padding: 0.15rem var(--space-4) 0.15rem 0; font-variant-numeric: tabular-nums; }
.ig-posts-header { margin-top: var(--space-6); }
.ig-posts-header h2 { margin: 0; }
.ig-sort { display: flex; gap: var(--space-4); font-size: var(--text-s); }
.ig-sort a { color: var(--muted); text-decoration: none; }
.ig-sort a.active { color: var(--fg); font-weight: 600; }
.ig-post { display: flex; gap: var(--space-4); align-items: flex-start; }
.ig-thumb { width: 88px; height: 88px; flex-shrink: 0; border-radius: var(--radius-m); object-fit: cover; display: flex; align-items: center; justify-content: center; background: var(--border); }
.ig-post-body { flex: 1; min-width: 0; }
.ig-caption { margin: 0.2rem 0 var(--space-2); overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.ig-stats { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-4); margin: 0; }
.ig-stats dt { color: var(--muted); font-size: var(--text-xs); }
.ig-stats dd { margin: 0; font-variant-numeric: tabular-nums; font-weight: 600; }
.ig-axis-bottom { color: var(--muted); font-size: var(--text-xs); margin-top: var(--space-1); }
@media (max-width: 480px) {
  .ig-thumb { width: 64px; height: 64px; }
  .ig-stats { display: grid; grid-template-columns: repeat(3, auto); justify-content: start; }
}

/* Quick input during a training (issue #34): the menu's link to it, the
   quick note and "Ich bin dabei". Big targets, for one thumb. */
header nav a.nav-live {
  background: var(--accent);
  color: var(--accent-fg);
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
  font-weight: 600;
  white-space: nowrap;
}
@media (hover: hover) { header nav a.nav-live:hover { color: var(--accent-fg); opacity: 0.85; } }
/* on phones its own line under the logo, the whole width */
/* no box around it: the fields get the whole width, like in an app */
.quick-note { display: flex; flex-direction: column; gap: var(--space-3); margin: var(--space-3) 0 var(--space-2); }
.quick-note label { display: flex; flex-direction: column; gap: var(--space-1); font-size: var(--text-s); color: var(--muted); }
.quick-note input, .quick-note textarea { font-size: var(--text-m); padding: var(--space-2) var(--space-3); color: var(--fg); }
/* the phone view is held in one hand during a rehearsal: a big field, a
   big button for the thumb */
.quick-note textarea { min-height: 9em; font-size: var(--text-l); }
.quick-note button, button.check-in { min-height: 3.5rem; padding: var(--space-3) var(--space-4); font-size: var(--text-l); }
button.check-in { margin: 0 0 var(--space-3); }
@media (max-width: 480px) { .quick-note button, button.check-in { width: 100%; } }
/* Today's training on the Trainings page stands out: "Heute" on its stub
   and as a sticker */

/* "Schnell notieren": suggestions for the exercise or format, below the field */
.quick-suggestions { list-style: none; margin: -0.35rem 0 0; padding: var(--space-1); background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-m); }
.quick-suggestions li { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-2); border-radius: var(--radius-s); cursor: pointer; color: var(--fg); }
/* the one picked with the arrow keys, and the one under the mouse: --wash,
   as the list is a white box itself */
.quick-suggestions li[aria-selected="true"] { background: var(--wash); }
@media (hover: hover) { .quick-suggestions li:hover { background: var(--wash); } }
.quick-suggestions li.new { color: var(--fg); font-weight: 600; }
.quick-suggestions .name { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.quick-suggestions .tag { text-transform: none; flex-shrink: 0; }
.quick-suggestions .muted { font-size: var(--text-s); flex-shrink: 0; }

/* The phone view during a training (training-live.html) */
.live-head { display: flex; align-items: center; gap: var(--space-2); margin: 0 0 var(--space-3); }
.live-head h1 { flex: 1; min-width: 0; margin: 0; font-family: var(--display); font-weight: normal; font-size: var(--display-m); line-height: 1.1; letter-spacing: 0.02em; text-transform: uppercase; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.live-head .tag { flex-shrink: 0; }
a.live-back { color: var(--fg); flex-shrink: 0; display: inline-grid; place-items: center; width: var(--tap); height: var(--tap); margin-left: calc(-1 * var(--space-3)); font-size: 1.4rem; line-height: 1; text-decoration: none; }
.quick-target { border: 0; margin: 0; padding: 0; min-width: 0; }
.quick-target legend { padding: 0; margin-bottom: var(--space-2); font-size: var(--text-s); color: var(--muted); }
.chip-row { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.quick-note label.chip-radio { display: inline-flex; flex-direction: row; font-size: var(--text-m); color: var(--fg); }
.chip-radio input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.chip-radio span { display: inline-block; padding: var(--space-2) var(--space-4); border: 1px solid var(--line); border-radius: var(--radius-pill); background: var(--card); cursor: pointer; }
.chip-radio input:checked + span { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.chip-radio input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }
/* under the mouse like the filter and place chips */
@media (hover: hover) { .chip-radio input:not(:checked) + span:hover { border-color: var(--accent); } }
.quick-other { display: flex; flex-direction: column; gap: var(--space-2); }
.quick-other[hidden] { display: none; }
/* "Bisher notiert": a ruled list, as everywhere else */
#live-noted:has(.live-noted) { border-top: 2px solid var(--fg); }
.card.live-noted { margin: 0; padding: var(--space-3); background: none; border: 0; border-bottom: 1px solid var(--border); border-radius: 0; }
.card.live-noted.private-note { border-left: 3px dashed var(--line); }
.quick-note .segmented label { flex-direction: row; font-size: var(--text-m); color: var(--fg); }
/* "Neutral" is chosen to begin with: marked by a ring, not filled */
.segmented label.point-chip-neutral:has(input:checked) { background: var(--card); color: var(--fg); box-shadow: inset 0 0 0 2px var(--fg); }
.live-noted-head { font-weight: 600; }
.live-points { list-style: none; padding: 0; margin: var(--space-1) 0 0; display: grid; gap: var(--space-1); }
.live-points li { display: flex; gap: var(--space-2); overflow-wrap: anywhere; }
.live-points li::before { flex-shrink: 0; font-weight: 700; }
.live-points .point-good::before { content: '✓'; color: var(--green); }
.live-points .point-bad::before { content: '↗'; color: var(--fg); }
.live-points .point-neutral::before { content: '•'; color: var(--muted); }
/* "Nur für mich": the whole line is the target, the box a size to hit */
.quick-note label.check-row { display: block; position: relative; min-height: var(--tap); padding: var(--space-2) 0 var(--space-2) 2.25rem; font-size: var(--text-m); color: var(--fg); cursor: pointer; }
.check-row input { position: absolute; left: 0; top: var(--space-2); margin: 0; }
.check-row .muted { font-size: var(--text-s); }
.private-note { border-style: dashed; }
.private-actions { margin-top: var(--space-2); justify-content: flex-start; }

/* "Kommst du?" (issue #35): on an event's page and, small, on Termine's cards.
   A no is shown in grey, so a yes stands out. */
/* A switch of radio buttons (docs/design-system.md), looking like the answer
   switch below: e.g. good, bad or neutral in a show's look back */
.segmented {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 1.5px solid var(--muted);
  border-radius: var(--radius-m);
  overflow: hidden;
  background: var(--card);
}
.segmented label { position: relative; display: flex; align-items: center; justify-content: center; gap: var(--space-1); min-height: var(--tap); padding: var(--space-2); font-weight: 600; white-space: nowrap; cursor: pointer; }
.segmented label + label { border-left: 1.5px solid var(--muted); }
.segmented input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
.segmented label:has(input:checked) { background: var(--fg); color: var(--bg); }
.segmented label:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: -5px; }
/* the switch is a white box, so under the mouse --wash, not --card */
@media (hover: hover) { .segmented label:not(:has(input:checked)):hover { background: var(--wash); } }
@media (max-width: 480px) { .segmented label { font-size: var(--text-s); } }
/* The answer switch (docs/design-system.md): two halves of one control, a
   finger high, outlined in a colour you can see (not --border), the chosen
   half filled: a yes in the text colour, a no in grey, so a yes stands out */
.answer {
  display: grid;
  grid-template-columns: 1fr 1fr;
  max-width: 24rem;
  border: 1.5px solid var(--muted);
  border-radius: var(--radius-m);
  overflow: hidden;
  background: var(--card);
}
.answer button.toggle-chip {
  min-height: var(--tap);
  padding: var(--space-2);
  border: 0;
  border-radius: 0;
  white-space: nowrap;
  background: transparent;
  color: var(--fg);
  font-size: var(--text-m);
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
}
.answer button.toggle-chip + button.toggle-chip { border-left: 1.5px solid var(--muted); }
.answer button.response-yes::before { content: '✓' / ''; }
.answer button.response-no::before { content: '✕' / ''; }
.answer button.toggle-chip::before { font-weight: 700; color: var(--muted); }
.answer button.toggle-chip.on::before { color: inherit; }
/* a chosen yes is solid in the text colour: no kind's colour, so it doesn't melt into a show's stub */
.answer button.response-yes.on { background: var(--fg); color: var(--bg); }
/* a chosen no is a quiet grey, so only a yes lights up, also in dark mode */
.answer button.response-no.on { background: color-mix(in srgb, var(--muted) 30%, var(--card)); color: var(--fg); box-shadow: inset 0 0 0 2px var(--fg); font-weight: 700; }
/* once answered, the other half's mark goes, so the state reads without colour */
.answer:has(.on) button:not(.on)::before { content: none; }
/* the narrowest phones: a ticket's switch still fits on one line */
@media (max-width: 380px) { .card-responses button.toggle-chip { font-size: var(--text-s); } }
/* the switch is a white box: --wash under the mouse, not --card */
@media (hover: hover) { .answer button.toggle-chip:not(.on):hover { background: var(--wash); opacity: 1; filter: none; } }
/* "Kommst du?" on an event's page: the switch and who said what, no box */
.card.responses { padding: 0; background: none; border: 0; border-radius: 0; }
.response-note-box > summary { display: inline-flex; align-items: center; min-height: var(--tap); margin-top: var(--space-1); list-style: none; cursor: pointer; color: var(--fg); font-weight: 600; font-size: var(--text-s); }
.response-note-box > summary::-webkit-details-marker { display: none; }
.response-note-box[open] > summary { display: none; }
.response-note { display: flex; flex-direction: column; gap: var(--space-1); margin-top: var(--space-3); font-size: var(--text-s); color: var(--muted); }
.response-lists .answer-line { margin-top: var(--space-3); }
.response-lists > p { margin: var(--space-3) 0 var(--space-1); }
.response-lists > p.muted { font-size: var(--text-s); }
.card-responses { margin-top: var(--space-3); }
.reminder-choice { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-2); }
.reminder-choice select { width: auto; }

/* Aktivität (issue #36) */
.activity-list { list-style: none; padding: 0; margin: 0; }
.activity-entry { display: grid; gap: 0.2rem; }
.activity-entry.new { border-left: 3px solid var(--accent); }
.activity-head .tag { margin-left: var(--space-1); }
.activity-target a { font-weight: 600; color: var(--fg); text-decoration: none; }
@media (hover: hover) { .activity-target a:hover { text-decoration: underline; text-decoration-color: var(--accent); text-decoration-thickness: 2px; } }
.activity-lines { margin: 0.15rem 0 0; padding-left: 0; list-style: none; color: var(--muted); }
/* who and when: the time in the display face, as an archive's date */
.activity-head strong { font-weight: 600; }
.activity-head .muted { font-family: var(--display); font-size: var(--text-l); letter-spacing: 0.03em; margin-left: var(--space-1); }
.activity-lines li { overflow-wrap: anywhere; }
.activity-more summary { cursor: pointer; color: var(--muted); }
.activity-toggle { font-size: var(--text-s); }

/* Übersicht, the start page (issue #37) */
.home-live { display: flex; text-align: center; margin: -0.2rem 0 var(--space-2); }
.home-todo { list-style: none; margin: 0; padding: 0; border-top: 2px solid var(--fg); }
/* what's yours to do: lines like the other lists, each leading somewhere */
.home-todo > li { padding: var(--space-3); border-bottom: 1px solid var(--border); }
.home-todo a { color: var(--fg); font-weight: 600; text-decoration: none; }
.home-todo a::after { content: ' →'; color: var(--muted); }
@media (hover: hover) { .home-todo a:hover { text-decoration: underline; text-decoration-color: var(--accent); } }

/* Under a form for a new event: what's already on those days, a ruled list
   whose rows lead to it (public/same-days.js); when the server finds a
   lookalike, the lead-in is bold */
.same-days { margin-top: var(--space-4); }
.same-days-lead { margin: 0 0 var(--space-2); color: var(--muted); }
.same-days-lead.warn { color: var(--fg); font-weight: 600; }
.same-days-list { list-style: none; margin: 0; padding: 0; border-top: 2px solid var(--fg); }
.same-days-list > li { border-bottom: 1px solid var(--border); }
.same-days-list a { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-2); min-height: var(--tap); padding: var(--space-2) 0; color: var(--fg); text-decoration: none; }
.same-days-list a::after { content: '→'; margin-left: auto; color: var(--muted); }
.same-days-title { font-weight: 600; }
@media (hover: hover) { .same-days-list a:hover .same-days-title { text-decoration: underline; text-decoration-color: var(--accent); } }

/* The demo (demo.js) */
/* no connection (lib.js): a strip at the bottom, in the toast's colours */
.offline-bar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 900; padding: var(--space-2) max(16px, env(safe-area-inset-left, 0px)) max(var(--space-2), env(safe-area-inset-bottom, 0px)); background: var(--fg); color: var(--bg); font-size: var(--text-s); text-align: center; }
body:has(.offline-bar) { padding-bottom: 4.5rem; }
@media (min-width: 481px) { body:has(.offline-bar) #toast-container { bottom: calc(var(--space-5) + 3rem); } }
@media (max-width: 767px) {
  body:has(.nav-pages) .offline-bar { bottom: calc(var(--tabbar) + env(safe-area-inset-bottom, 0px)); padding-bottom: var(--space-2); }
  body:has(.nav-pages):has(.offline-bar) { padding-bottom: calc(var(--tabbar) + 3rem + env(safe-area-inset-bottom, 0px)); }
}
/* 481–767 px: toasts are at the bottom right there, so above the bar */
@media (min-width: 481px) and (max-width: 767px) {
  body:has(.nav-pages) #toast-container { bottom: calc(var(--tabbar) + var(--space-3) + env(safe-area-inset-bottom, 0px)); }
  body:has(.nav-pages):has(.offline-bar) #toast-container { bottom: calc(var(--tabbar) + var(--space-3) + 3rem + env(safe-area-inset-bottom, 0px)); }
}
@media print { .offline-bar { display: none; } }
.demo-banner { background: var(--accent); color: var(--accent-fg); text-align: center; font-size: var(--text-s); padding: var(--space-2) max(16px, env(safe-area-inset-left, 0px)); }
.demo-banner a { color: inherit; font-weight: 600; }

/* What Daisy can do (daisy.html): a ruled list, each a bold line, what it
   covers and an example to say */
.chat-skills { list-style: none; margin: var(--space-2) 0 var(--space-4); padding: 0; border-top: 2px solid var(--fg); }
.chat-skills > li { border-bottom: 1px solid var(--border); padding: var(--space-2) 0; }
.chat-skills > li > * { display: block; }
.chat-say { color: var(--muted); font-style: italic; }
.chat-skills-link { white-space: nowrap; } /* under the chat input, linking here */

/* Daisy in the demo: the examples to tap (routes/assistant-demo.js) */
/* the demo's examples: a ruled list of lines to tap, like "Für dich zu tun",
   not a stack of raised buttons */
.chat-examples { list-style: none; margin: var(--space-2) 0 var(--space-5); padding: 0; border-top: 2px solid var(--fg); }
.chat-examples > li { border-bottom: 1px solid var(--border); }
button.quiet.chat-example { display: block; width: 100%; padding: var(--space-3); text-align: left; white-space: normal; color: var(--fg); }
button.quiet.chat-example::after { content: ' →'; color: var(--muted); }

/* Everything clickable shows it's under the mouse (design system): a word
   that opens something underlines in the accent (and a muted one turns
   --fg); a link standing on its own gets an accent underline; the arrow
   back from Schnell notieren a round patch; a person's row on Verwaltung,
   inside its box, --wash. Found by make review-shots ("No visible state"). */
@media (hover: hover) {
  details.history > summary:hover,
  .history-diff summary:hover,
  .changelog-older > summary:hover,
  .changelog-minor > summary:hover,
  .activity-more summary:hover,
  .response-note-box > summary:hover,
  .subscribe-help > summary:hover { color: var(--fg); text-decoration: underline; text-decoration-color: var(--accent); text-decoration-thickness: 2px; }
  .section-head > a:not(.button):hover,
  .page-header > a:not(.button):hover,
  .activity-toggle a:hover,
  .details-tickets a:hover,
  .played-in a:hover { text-decoration: underline; text-decoration-color: var(--accent); text-decoration-thickness: 2px; }
  a.live-back:hover { background: var(--card); border-radius: 50%; }
  details.person > summary:hover { background: var(--wash); }
}

/* "Dateien" on an event's page (pages/files.js): a ruled list, each row a
   link over its whole width (a picture's preview or a sheet, the name, who,
   when, how big) and "Löschen" beside it for whoever may */
.file-list { list-style: none; margin: 0 0 var(--space-4); padding: 0; border-top: 1px solid var(--border); }
.file-row { display: flex; align-items: center; gap: var(--space-1); border-bottom: 1px solid var(--border); }
.file-link { flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--space-3); min-height: var(--tap); padding: var(--space-2) 0; color: var(--fg); text-decoration: none; }
@media (hover: hover) { .file-link:hover .file-name { text-decoration: underline; text-decoration-color: var(--accent); } }
.file-thumb { flex-shrink: 0; width: 48px; height: 48px; border-radius: var(--radius-s); object-fit: cover; background: var(--wash); }
.file-sheet { display: flex; align-items: center; justify-content: center; color: var(--muted); }
.file-sheet svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.file-text { min-width: 0; display: flex; flex-direction: column; }
.file-name { font-weight: 600; overflow-wrap: anywhere; }
.file-text .muted { font-size: var(--text-s); }

/* While files go up: the name and "37 %" over a bar, "Abbrechen" below it
   (pages/files.js). The bar is filled in --fg, not the accent: it shows
   something, it isn't something to do. Drawn ourselves, so Safari's
   own blue bar doesn't show. */
.upload-progress { margin: 0 0 var(--space-4); padding: var(--space-2) 0; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.upload-progress[hidden] { display: none; }
.upload-text { display: flex; justify-content: space-between; gap: var(--space-3); margin: 0 0 var(--space-2); }
.upload-name { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.upload-percent { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.upload-progress progress { -webkit-appearance: none; appearance: none; display: block; width: 100%; height: 8px; border: 0; border-radius: 4px; background: var(--wash); overflow: hidden; }
.upload-progress progress::-webkit-progress-bar { background: var(--wash); border-radius: 4px; }
.upload-progress progress::-webkit-progress-value { background: var(--fg); border-radius: 4px; }
.upload-progress progress::-moz-progress-bar { background: var(--fg); border-radius: 4px; }
.upload-progress .quiet { margin-top: var(--space-1); }

/* Pictures and videos under "Dateien": a grid of square tiles, three across on
   a phone, that open the viewer; a video shows its first frame and a play
   sign */
.file-gallery { list-style: none; margin: 0 0 var(--space-4); padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: var(--space-1); }

/* "Aufrufe" (pages/page-views.js): a ruled table, each page's name, then its
   counts right-aligned in tabular figures, so they line up */
.stats-table { width: 100%; border-collapse: collapse; margin: var(--space-3) 0; border-top: 1px solid var(--border); }
.stats-table th, .stats-table td { padding: var(--space-2) var(--space-2) var(--space-2) 0; border-bottom: 1px solid var(--border); text-align: left; font-weight: normal; }
.stats-table thead th { color: var(--muted); font-size: var(--text-s); }
.stats-table td, .stats-table thead th:not(:first-child) { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; padding-right: 0; padding-left: var(--space-3); }
.stats-table tbody th { overflow-wrap: anywhere; }

/* "Fotos & Videos" (pages/photos.js): one group per event, under a thin
   rule: its title as a link in bold (not the display face: there are
   many), day, kind and how many in --muted, then its tiles; "Neuere" and
   "Ältere Termine" at the end */
.photo-group { border-top: 1px solid var(--border); padding-top: var(--space-3); }
.photo-group-title { font-family: inherit; font-size: var(--text-l); font-weight: 600; letter-spacing: normal; text-transform: none; margin: 0; }
.photo-group-title a { color: var(--fg); text-decoration: none; display: inline-block; min-height: var(--tap); padding: var(--space-2) 0 0; }
@media (hover: hover) { .photo-group-title a:hover { text-decoration: underline; text-decoration-color: var(--accent); text-decoration-thickness: 2px; } }
.photo-group > .muted { margin: 0 0 var(--space-2); font-size: var(--text-s); }
.photo-pager { display: flex; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; margin-top: var(--space-4); }
.photo-pager .older { margin-left: auto; }
.gallery-tile { position: relative; display: block; aspect-ratio: 1; overflow: hidden; border-radius: var(--radius-s); background: var(--wash); }
.gallery-tile img, .gallery-tile video { width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none; }
@media (hover: hover) { .gallery-tile:hover img, .gallery-tile:hover video { opacity: 0.85; } }
.gallery-tile:focus-visible { outline-offset: 2px; }
.gallery-play { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #ffffff; }
.gallery-play svg { width: 40px; height: 40px; padding: 8px; border-radius: 50%; background: rgb(0 0 0 / 0.55); fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* The viewer: a picture or video as big as the screen allows, on black in
   light and dark alike (a photo's own colours, nothing around them), the bar
   with "3 / 27", Original, Löschen and ✕ above, name and who below */
dialog.viewer { width: 100vw; height: 100dvh; max-width: none; max-height: none; margin: 0; padding: env(safe-area-inset-top, 0) env(safe-area-inset-right, 0) env(safe-area-inset-bottom, 0) env(safe-area-inset-left, 0); border: 0; background: #0b0a0b; color: #ffffff; }
dialog.viewer[open] { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; }
dialog.viewer::backdrop { background: #0b0a0b; }
.viewer-bar { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-1) var(--space-2) var(--space-1) var(--space-4); }
.viewer-count { flex: 1; font-variant-numeric: tabular-nums; color: rgb(255 255 255 / 0.75); }
.viewer-open { color: #ffffff; min-height: var(--tap); display: inline-flex; align-items: center; }
dialog.viewer button.viewer-delete { min-height: var(--tap); padding: 0 var(--space-2); background: none; border: 0; box-shadow: none; color: rgb(255 255 255 / 0.75); font-weight: 600; }
dialog.viewer button.viewer-delete.danger { background: var(--danger); color: var(--danger-fg); }
dialog.viewer button.viewer-button { width: var(--tap); min-width: var(--tap); padding: 0; background: rgb(0 0 0 / 0.45); border: 0; border-radius: 50%; box-shadow: none; color: #ffffff; }
dialog.viewer button.viewer-button svg { width: 24px; height: 24px; }
@media (hover: hover) { dialog.viewer button.viewer-button:hover, dialog.viewer button.viewer-delete:not(.danger):hover { background: rgb(255 255 255 / 0.18); color: #ffffff; } }
.viewer-stage { position: relative; min-height: 0; display: flex; align-items: center; justify-content: center; }
.viewer-media { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; touch-action: pan-y pinch-zoom; }
.viewer-media img, .viewer-media video { max-width: 100%; max-height: 100%; object-fit: contain; user-select: none; -webkit-user-drag: none; }
.viewer-prev, .viewer-next { position: absolute; top: 50%; transform: translateY(-50%); z-index: 1; }
dialog.viewer button.viewer-prev { left: var(--space-2); }
dialog.viewer button.viewer-next { right: var(--space-2); }
dialog.viewer button.viewer-prev:active, dialog.viewer button.viewer-next:active { transform: translateY(-50%); }
.viewer-caption { margin: 0; padding: var(--space-2) var(--space-4) var(--space-3); display: flex; flex-direction: column; gap: 2px; overflow-wrap: anywhere; }
.viewer-caption span { font-size: var(--text-s); color: rgb(255 255 255 / 0.75); }
dialog.viewer :focus-visible { outline-color: #ffffff; }

/* "Feedback zu dieser Seite" (public/page-feedback.js): a window over the
   page, from the bottom edge on a phone (in reach of the thumb), in the
   middle on wider screens; the page dimmed behind it */
dialog.page-feedback { box-sizing: border-box; width: 100%; max-width: 32rem; max-height: calc(100dvh - var(--space-4)); margin: auto auto 0; padding: var(--space-4) var(--space-3) calc(var(--space-3) + env(safe-area-inset-bottom, 0px)); border: 0; border-radius: var(--radius-l) var(--radius-l) 0 0; background: var(--bg); color: var(--fg); box-shadow: 0 -8px 32px rgb(0 0 0 / 0.2); }
dialog.page-feedback::backdrop { background: rgb(0 0 0 / 0.45); }
@media (min-width: 640px) { dialog.page-feedback { margin: auto; padding-bottom: var(--space-3); border-radius: var(--radius-l); box-shadow: 0 8px 32px rgb(0 0 0 / 0.2); } }
dialog.page-feedback h2 { margin: 0 0 var(--space-1); }
dialog.page-feedback textarea { box-sizing: border-box; width: 100%; min-height: 7em; }
.page-feedback-about { margin: 0 0 var(--space-3); color: var(--muted); font-size: var(--text-s); }
.page-feedback-about strong { color: var(--fg); font-weight: 600; }
.page-feedback-note { margin: var(--space-2) 0 0; color: var(--muted); font-size: var(--text-s); }
.page-feedback-error { margin: var(--space-2) 0 0; color: var(--danger); font-size: var(--text-s); }
.page-feedback-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }
/* on "Wünsche & Feedback": which page an entry is about */
.feedback-page { margin: 0 0 var(--space-1); font-size: var(--text-s); }

/* "Abwesend" (public/away-form.js, routes/absence.js): on Mein Konto and
   under each member on Verwaltung */
.away-form { display: grid; gap: var(--space-3); }
.away-dates { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); }
.away-dates label, .away-reason { display: grid; gap: var(--space-1); color: var(--muted); font-size: var(--text-s); }
.away-dates input, .away-reason input { box-sizing: border-box; width: 100%; min-width: 0; color: var(--fg); font-size: var(--text-m); }
.away-set { font-size: var(--text-l); }
.person-away { margin-top: var(--space-3); padding-top: var(--space-3); border-top: 1px solid var(--border); }
.person-away h3 { margin: 0 0 var(--space-2); }
/* above "Ich komme / Ich kann nicht" when you're away for all of it and
   haven't answered: why you count as a no, a quiet line rather than a box */
.away-hint { margin: 0 0 var(--space-2); padding: var(--space-1) 0 var(--space-1) var(--space-3); border-left: 3px solid var(--border); font-size: var(--text-s); }
