/* Weingruen corporate identity for the pretix presale shop.
 *
 * Token source of truth: website/tailwind.config.ts. Changes there and here
 * have to move together.
 *
 * Delivered by pretix_weingruen_theme/signals.py via the global_html_head
 * signal, so it lands on every presale page without per-event activation.
 * Style loop while working on it: deploy/pretix/sync-theme.sh
 *
 * Counterpart for the embedded widget (which renders in the WEBSITE's DOM,
 * not here): the .pretix-widget-host block at the end of
 * website/src/app/globals.css.
 *
 * pretix presale is Bootstrap 3 based. We hook onto its classes only — no
 * template overrides — so a pretix upgrade cannot break the shop, only make
 * parts of this file ineffective. The mandatory smoke test after an upgrade
 * is in deploy/pretix/README.md.
 */

/* ---------- Fonts ---------- */
/* Relative URLs on purpose: collectstatic rewrites them to the hashed file
   names while collecting, so these resolve to /static/weingruen/fonts/<hash>. */
@font-face {
  font-family: "Aller Display";
  src: url("fonts/AllerDisplay.cbf673593245.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Barlow Condensed";
  src: url("fonts/BarlowCondensed-Regular.03efc33222dc.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Barlow Condensed";
  src: url("fonts/BarlowCondensed-Medium.2b10301ce419.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Barlow Condensed";
  src: url("fonts/BarlowCondensed-SemiBold.181046da6cb0.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Barlow Condensed";
  src: url("fonts/BarlowCondensed-Bold.52b5f967843d.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* ---------- Tokens ---------- */
:root {
  --wg-olive: #838332;
  --wg-olive-deep: #6b6b26;
  --wg-olive-soft: #a5a551;
  --wg-olive-tint: #e6e5c8;
  --wg-cream: #f5f1dd;
  --wg-cream-warm: #fbf8ec;
  --wg-ink: #020203;
  --wg-paper: #ffffff;
  --wg-red: #c5212b;

  --wg-muted: rgba(2, 2, 3, 0.6);
  --wg-line: rgba(2, 2, 3, 0.15);

  --wg-radius-card: 18px;
  --wg-radius-chip: 14px;
  --wg-radius-pill: 999px;
  --wg-shadow-soft: 0 1px 0 rgba(2, 2, 3, 0.06), 0 2px 6px rgba(2, 2, 3, 0.05);

  --wg-display: "Aller Display", Georgia, serif;
  --wg-sans: "Barlow Condensed", system-ui, sans-serif;

  /* Pull pretix' own variable along, so rules generated from the organizer's
     shop-design settings do not fight this file over the body font. */
  --pretix-font-family-sans-serif: "Barlow Condensed", system-ui, sans-serif;
}

/* ---------- Surfaces ---------- */
body {
  background-color: var(--wg-cream);
  color: var(--wg-ink);
  font-family: var(--wg-sans);
  font-weight: 500;
  -webkit-font-smoothing: antialiased;
}

.container,
.container-fluid {
  color: var(--wg-ink);
}

/* pretix frames content in Bootstrap 3 panels. Those become our cards: paper
   on cream, soft edge instead of a hard border. */
.panel,
.panel-default,
.well,
.thumbnail {
  background-color: var(--wg-paper);
  border: 0;
  border-radius: var(--wg-radius-card);
  box-shadow: var(--wg-shadow-soft);
}

.panel-heading,
.panel-footer {
  background-color: transparent;
  border-color: var(--wg-line);
}

hr {
  border-top-color: var(--wg-line);
}

/* ---------- Typography ---------- */
/* .price covers every price on every screen — pretix puts that class on the
   single price, the cart line and the cart total alike (checked on the cart
   and checkout screens 2026-08-27), so no separate total/summary selectors
   are needed. */
h1,
h2,
h3,
.panel-title,
.price {
  font-family: var(--wg-display);
  text-transform: uppercase;
  letter-spacing: -0.01em;
  line-height: 0.95;
  color: var(--wg-ink);
}

h1 {
  font-size: clamp(2rem, 6vw, 3.25rem);
  margin-bottom: 0.5em;
}

h2 {
  font-size: clamp(1.5rem, 4vw, 2.25rem);
}

h3,
.panel-title {
  font-size: 1.25rem;
}

small,
.small,
.text-muted,
.help-block {
  color: var(--wg-muted);
  font-family: var(--wg-sans);
}

a {
  color: var(--wg-olive-deep);
  text-decoration: underline;
  text-underline-offset: 2px;
}

a:hover,
a:focus {
  color: var(--wg-ink);
}

/* ---------- Focus ---------- */
/* Replaced, never removed: pretix is built for EEA accessibility and the shop
   has to stay keyboard operable. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--wg-olive-deep);
  outline-offset: 2px;
}

/* ---------- Buttons ---------- */
/* Mirrored from website/src/components/Button.tsx: rounded-pill, px-6 py-3,
   text-sm, font-semibold, uppercase, tracking-wide. */
.btn {
  font-family: var(--wg-sans);
  font-size: 0.875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.025em;
  border-radius: var(--wg-radius-pill);
  padding: 0.75rem 1.5rem;
  border: 0;
  transition: filter 0.15s ease, background-color 0.15s ease;
}

.btn-lg {
  font-size: 1rem;
  padding: 0.875rem 1.75rem;
}

.btn-xs {
  font-size: 0.75rem;
  padding: 0.35rem 0.9rem;
}

.btn-primary,
.btn-success {
  background-color: var(--wg-olive-deep);
  color: var(--wg-cream);
}

.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active,
.btn-success:hover,
.btn-success:focus {
  background-color: var(--wg-olive-deep);
  color: var(--wg-cream);
  filter: brightness(0.9);
}

.btn-default {
  background-color: transparent;
  border: 2px solid var(--wg-line);
  color: var(--wg-ink);
}

.btn-default:hover,
.btn-default:focus {
  background-color: rgba(2, 2, 3, 0.05);
  color: var(--wg-ink);
}

.btn-danger {
  background-color: var(--wg-red);
  color: var(--wg-cream);
}

.btn[disabled],
.btn.disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Tap feedback like on the website, behind the reduced-motion guard. */
@media (prefers-reduced-motion: no-preference) {
  .btn:active {
    transform: scale(0.98);
  }
}

/* ---------- Form fields ---------- */
.form-control,
select,
textarea,
input[type="text"],
input[type="email"],
input[type="tel"],
input[type="number"],
input[type="password"] {
  background-color: var(--wg-cream-warm);
  border: 1px solid var(--wg-line);
  border-radius: var(--wg-radius-chip);
  color: var(--wg-ink);
  font-family: var(--wg-sans);
  box-shadow: none;
}

.form-control:focus {
  border-color: var(--wg-olive-deep);
  box-shadow: none;
}

label,
.control-label {
  font-family: var(--wg-sans);
  font-weight: 600;
  color: var(--wg-ink);
}

/* Quantity stepper on the product page (input-item-count-group). The two
   round pill buttons of the generic .btn rule would collide with the number
   field between them, so this group keeps square-ish ends. */
.input-item-count-group .btn,
.input-group-btn .btn {
  padding: 0.5rem 0.85rem;
  border-radius: var(--wg-radius-chip);
}

.input-item-count {
  text-align: center;
  font-family: var(--wg-sans);
  font-weight: 600;
}

/* Not-yet-available item (e.g. a later price phase): a box as big as the
   quantity stepper above instead of small grey text (Luca 22.10.). */
.availability-box.unavailable p {
  margin: 0;
}

.availability-box.unavailable small {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 2.6rem;
  padding: 0.5rem 0.85rem;
  border: 1px solid var(--wg-line);
  border-radius: var(--wg-radius-chip);
  background: var(--wg-olive-tint);
  color: var(--wg-muted);
  font-family: var(--wg-sans);
  font-size: 1rem;
  font-weight: 600;
}

/* Price phases (Cooked by SvenWach, item 10 = Phase 2): label it "Bald
   verfügbar". Scoped by item id because the same box also shows items whose
   sale has ended, where "bald" would be wrong. */
#item-10 .availability-box.unavailable small {
  font-size: 0;
}

#item-10 .availability-box.unavailable small::after {
  content: "Bald verfügbar";
  font-size: 1rem;
}

/* ---------- Messages ---------- */
.alert {
  border: 0;
  border-radius: var(--wg-radius-card);
  font-family: var(--wg-sans);
}

.alert-success,
.alert-info {
  background-color: var(--wg-olive-tint);
  color: var(--wg-ink);
}

.alert-warning {
  background-color: var(--wg-cream-warm);
  color: var(--wg-ink);
  border: 1px solid var(--wg-line);
}

.alert-danger {
  background-color: rgba(197, 33, 43, 0.1);
  color: var(--wg-red);
}

/* The test-mode banner must stay loud — it is a warning that this shop is not
   selling for real. Deliberately NOT toned down into the palette. */
.alert-testmode {
  background-color: var(--wg-red);
  color: var(--wg-cream);
  border: 0;
}

.has-error .form-control {
  border-color: var(--wg-red);
}

/* ---------- Badges and availability ---------- */
.label,
.badge {
  border-radius: var(--wg-radius-chip);
  font-family: var(--wg-sans);
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 0.25em 0.7em;
}

.availability-box.available,
.label-success {
  background-color: var(--wg-olive-deep);
  color: var(--wg-cream);
}

.availability-box.unavailable,
.label-danger {
  background-color: var(--wg-red);
  color: var(--wg-cream);
}

/* ---------- Product list ---------- */
.product-row,
.variation {
  border-color: var(--wg-line);
}

.item-category h3,
.item-category > h3 {
  font-family: var(--wg-display);
  text-transform: uppercase;
  letter-spacing: -0.01em;
}

.product-description {
  color: var(--wg-muted);
}

.product-row .price,
.variation .price,
.price {
  font-family: var(--wg-display);
  font-size: 1.35rem;
  letter-spacing: -0.01em;
  color: var(--wg-ink);
}

/* ---------- Progress ---------- */
.progress {
  background-color: var(--wg-olive-tint);
  border-radius: var(--wg-radius-pill);
  box-shadow: none;
}

.progress-bar,
.progress-bar-success {
  background-color: var(--wg-olive-deep);
}

/* Availability pill: the .label/.badge radius rule above does not reach it,
   it is its own element. */
.availability-box {
  border-radius: var(--wg-radius-chip);
}

/* pretix also puts .availability-box.available on the whole cart-control
   column of a product or add-on row (the "Auswählen" checkbox button, the
   count input). The chip rule above painted that column olive behind the
   button, and the button's pill and focus ring ran over the chip edge
   (seen 2026-10-22 on the Silvester add-ons). Only a plain status word keeps
   the chip; a column holding controls stays transparent. */
.availability-box:has(.btn-checkbox, .input-item-count-group, input) {
  background-color: transparent;
  color: inherit;
  padding: 0;
  border-radius: 0;
}

/* Selected state of the checkbox button: pretix only greys it, which reads
   as disabled next to our olive buttons. */
.btn-checkbox.btn-checkbox-checked,
.btn-checkbox.btn-checkbox-checked:hover,
.btn-checkbox.btn-checkbox-checked:focus {
  background-color: var(--wg-olive-deep);
  border-color: var(--wg-olive-deep);
  color: var(--wg-cream);
}

/* ---------- Page frame ---------- */
/* Real DOM of a presale page (checked 2026-08-27 against
   /weingruen/tasting/17/):
 *
 *   body
 *     > nav.sr-only            skip link
 *     > header                 organizer header image lives here; EMPTY and
 *                              0px tall until one is uploaded in the admin
 *     > div.container.main-box the whole page content, white
 *     > footer                 test-mode banner + "powered by pretix"
 *
 * So .main-box is the page card: cream page behind it, paper card on top.
 * .page-header is NOT the site header — it is the H1 block inside the
 * content container, so it stays a plain title with our rule colour rather
 * than becoming a coloured band.
 */
.main-box {
  background-color: var(--wg-paper);
  border-radius: var(--wg-radius-card);
  box-shadow: var(--wg-shadow-soft);
  padding: 2rem;
  margin-top: 2rem;
  margin-bottom: 2rem;
}

.page-header {
  border-bottom: 1px solid var(--wg-line);
  padding-bottom: 0.75rem;
  margin-bottom: 1.5rem;
}

.page-header h1 a,
.page-header h1 a:hover {
  color: var(--wg-ink);
  text-decoration: none;
}

/* Organizer header image, once one is uploaded (see deploy/pretix/README.md,
   "Shop design"). Guarded by :has(img), NOT :not(:empty): the empty header
   still holds whitespace and an empty <div>, so :empty never matches and the
   olive band would be declared on a 0px element. */
body > header:has(img) {
  background-color: var(--wg-olive-deep);
  padding: 1.5rem 0;
}

body > header img {
  max-height: 72px;
  width: auto;
}

/* ---------- Footer ---------- */
footer {
  color: var(--wg-muted);
  font-family: var(--wg-sans);
  padding: 1.5rem 0 2.5rem;
}

footer a {
  color: var(--wg-olive-deep);
}

/* ---------- Mobile ---------- */
@media (max-width: 767px) {
  .main-box {
    padding: 1.25rem;
    margin-top: 1rem;
    border-radius: var(--wg-radius-chip);
  }
  .btn-block {
    padding: 0.875rem 1.25rem;
  }
}

/* ---------- pretix brand variables ----------
 * pretix generates /<organizer>/theme.css from the shop-design colours in the
 * admin and presale.css consumes those variables heavily (61 uses of
 * --pretix-brand-primary alone). Overriding them here flips every one of those
 * rules at once, instead of us chasing individual selectors.
 *
 * The derived shades are NOT guesses: they are produced with pretix' own LESS
 * operations (lighten/darken/tint/shade/saturate in HSL), an implementation
 * validated against pretix' published purple output — 17 of 17 values matched
 * (one after fixing half-up rounding).
 *
 * CONSEQUENCE, on purpose: this block WINS over the colour fields in the
 * admin. Changing "Primary color" there no longer changes the shop. That is
 * the intent — one CI look for all three brands, versioned in the repo, immune
 * to a DB rebuild. To change the palette, change it here.
 *
 * primary + success = olive-deep #6B6B26 (olive IS the brand green).
 * danger = accent-red #C5212B. info + warning keep pretix' defaults: they are
 * neutral, rarely surfaced, and recolouring them buys nothing.
 *
 * Note: --pretix-brand-primary-darken-30 computes to #000000 because
 * olive-deep already sits at L=28%. It is used twice, both times for a deep
 * border; black reads fine on cream.
 */
:root {
  /* primary */
  --pretix-brand-primary: #6b6b26;
  --pretix-brand-primary-darken-10: #454519;
  --pretix-brand-primary-darken-15: #333312;
  --pretix-brand-primary-darken-17: #2b2b0f;
  --pretix-brand-primary-darken-20: #20200b;
  --pretix-brand-primary-darken-30: #000000;
  --pretix-brand-primary-darken-5: #58581f;
  --pretix-brand-primary-lighten-20: #b6b641;
  --pretix-brand-primary-lighten-23-saturate-2: #c1c146;
  --pretix-brand-primary-lighten-28-saturate-20: #dbdb45;
  --pretix-brand-primary-lighten-30: #c7c763;
  --pretix-brand-primary-lighten-40: #d5d588;
  --pretix-brand-primary-lighten-48: #dfdfa6;
  --pretix-brand-primary-lighten-5: #7e7e2d;
  --pretix-brand-primary-lighten-50: #e2e2ae;
  --pretix-brand-primary-lighten-53: #e6e6b9;
  --pretix-brand-primary-lighten-55: #e9e9c1;
  --pretix-brand-primary-shade-25: #50501d;
  --pretix-brand-primary-shade-42: #3e3e16;
  --pretix-brand-primary-tint-90: #f0f0e9;

  /* success */
  --pretix-brand-success: #6b6b26;
  --pretix-brand-success-darken-10: #454519;
  --pretix-brand-success-darken-12: #3e3e16;
  --pretix-brand-success-darken-15: #333312;
  --pretix-brand-success-darken-17: #2b2b0f;
  --pretix-brand-success-darken-20: #20200b;
  --pretix-brand-success-darken-30: #000000;
  --pretix-brand-success-darken-5: #58581f;
  --pretix-brand-success-lighten-10: #919133;
  --pretix-brand-success-lighten-20: #b6b641;
  --pretix-brand-success-lighten-30: #c7c763;
  --pretix-brand-success-lighten-35: #cece75;
  --pretix-brand-success-lighten-38: #d2d281;
  --pretix-brand-success-lighten-40: #d5d588;
  --pretix-brand-success-lighten-48: #dfdfa6;
  --pretix-brand-success-lighten-50: #e2e2ae;
  --pretix-brand-success-shade-25: #50501d;
  --pretix-brand-success-shade-42: #3e3e16;
  --pretix-brand-success-tint-50: #b5b593;
  --pretix-brand-success-tint-85: #e9e9de;

  /* danger */
  --pretix-brand-danger: #c5212b;
  --pretix-brand-danger-darken-10: #991a21;
  --pretix-brand-danger-darken-15: #83161d;
  --pretix-brand-danger-darken-17: #7b151b;
  --pretix-brand-danger-darken-20: #6e1218;
  --pretix-brand-danger-darken-30: #420b0e;
  --pretix-brand-danger-darken-5: #af1d26;
  --pretix-brand-danger-lighten-15: #e2515a;
  --pretix-brand-danger-lighten-25: #e97c83;
  --pretix-brand-danger-lighten-30: #ed9298;
  --pretix-brand-danger-lighten-33: #ef9fa4;
  --pretix-brand-danger-lighten-43: #f6cbce;
  --pretix-brand-danger-lighten-45: #f8d4d6;
  --pretix-brand-danger-lighten-5: #da2530;
  --pretix-brand-danger-shade-25: #941920;
  --pretix-brand-danger-shade-42: #721319;
  --pretix-brand-danger-tint-50: #e29095;
  --pretix-brand-danger-tint-85: #f6dedf;

  /* links */
  --pretix-link-contrast-color: #6b6b26;
  --pretix-link-hover-contrast-color: #333312;
}

/* Payment-method choice (checkout step "Zahlung" and "Zahlungsart ändern" on
   the order page): pretix prints the provider fee ("+ 1,10 €") right next to
   each radio button. Luca wants the choice list without that note; the fee
   still shows as its own line in the order summary and the total on the
   confirmation page, i.e. before "Zahlungspflichtig bestellen" (decision
   2026-09-03). DOM: checkout_payment.html / order_pay_change.html,
   <legend class="accordion-radio"> > <label class="panel-heading"> >
   <span class="panel-title"> > <strong class="pull-right flip">. */
.accordion-radio .panel-title > strong.pull-right {
  display: none;
}

/* ==========================================================================
   Ticketseiten-Umbau (Luca 2026-11-03, Entwurf „Beides bauen")
   Same face as the website event page: logo above the card, event image as
   banner, date/time as a fact box, product rows as cards, bigger stepper.
   CSS only, no template overrides: every rule targets pretix' own markup
   (base.html / index.html of pretix 2026.7, checked against
   /weingruen/wine-paint/64/ and /weingruen/ on 2026-11-03).
   ========================================================================== */

/* Logo above the card. The organizer has no header image, so the <header>
   is empty; the website wordmark fills it. Skipped as soon as a real header
   image is uploaded (:has(img)), so nothing shows twice. */
body > header:not(:has(img))::before {
  content: "";
  display: block;
  width: min(1170px, calc(100% - 30px));
  height: 64px;
  margin: 1.25rem auto 0;
  background: url("wortmarke-olive.26912ef4a319.svg") no-repeat left center / contain;
}

/* Card: frame instead of shadow (design rule 2026-10-28). */
.main-box {
  border: 1px solid var(--wg-line);
  box-shadow: none;
  margin-top: 1rem;
  padding: 2.5rem;
}

.page-header {
  border-bottom: 0;
  margin-bottom: 1rem;
}

.page-header h1 {
  font-size: clamp(2.25rem, 6vw, 3.75rem);
}

/* Event image as banner. Shows once the event has a header image with
   "full size" switched on (pretix renders .page-header.logo-large with
   img.event-logo, thumb 1170 px wide). It bleeds to the card edges. */
.page-header.logo-large {
  margin: -2.5rem -2.5rem 1.75rem;
  padding: 0;
}

.page-header.logo-large .event-logo {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--wg-radius-card) var(--wg-radius-card) 0 0;
}

/* Event title below the banner (setting "show title" with a header image). */
.content-header,
.subevent-head {
  font-family: var(--wg-display);
  text-transform: uppercase;
  font-size: clamp(2rem, 5vw, 3.25rem);
  line-height: 0.95;
  margin: 0.25rem 0 1rem;
}

/* Series date page without a banner: pretix prints the series name as h1
   and the date's name again as h2. The h1 becomes a small eyebrow, the date
   heading carries the page, so the same words do not stand twice in big. */
.main-box:has(.subevent-head) .page-header:not(.logo-large) h1 {
  font-family: var(--wg-sans);
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  margin: 0;
}

.main-box:has(.subevent-head) .page-header:not(.logo-large) h1 a {
  color: var(--wg-olive-deep);
}

/* Event text: readable line length and size. The frontpage text sits in a
   class-less <div> directly in #content. Only its direct <p> children are
   hit, so .info-row (own class) and the product rows keep their sizes. */
#content > div:not([class]) {
  max-width: 46rem; /* ~75 characters; ch is too narrow in a condensed face */
}

#content > div:not([class]) > p {
  font-size: 1.125rem;
  line-height: 1.55;
}

/* Date, time, place: one fact box instead of loose icon lines. */
.info-row {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  background: var(--wg-cream-warm);
  border: 1px solid var(--wg-line);
  border-radius: var(--wg-radius-chip);
  padding: 1rem 1.1rem;
  margin: 1.25rem 0 0;
  max-width: 34rem;
}

.info-row + .info-row {
  margin-top: 0.5rem;
}

.info-row .info-row-icon {
  flex: 0 0 2.5rem;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 8px;
  background: var(--wg-olive-tint);
  color: var(--wg-olive-deep);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.15rem;
  margin: 0;
  position: static;
}

.info-row p {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 600;
  line-height: 1.4;
}

.info-row p > time:first-child {
  font-size: 1.2rem;
}

/* "Zu anderem Termin wechseln": a quiet outlined bar instead of grey. */
details.panel > summary.panel-heading {
  background: transparent;
  border: 1.5px solid var(--wg-olive-deep);
  border-radius: var(--wg-radius-pill);
  padding: 0.7rem 1.25rem;
  cursor: pointer;
}

details.panel > summary.panel-heading .panel-title {
  font-family: var(--wg-sans);
  font-size: 1rem;
  letter-spacing: 0.04em;
  color: var(--wg-olive-deep);
}

details.panel[open] > summary.panel-heading {
  border-radius: var(--wg-radius-chip) var(--wg-radius-chip) 0 0;
}

details.panel {
  box-shadow: none;
  background: transparent;
  margin-bottom: 1.5rem;
}

/* Panel headings ("Wählen Sie einen Termin aus", "Nächste
   Veranstaltungen"): pretix paints them grey via .panel-default > ..., which
   beats the generic transparent rule further up. */
.panel-default > .panel-heading {
  background-color: transparent;
}

/* Product rows become cards. */
.item-category {
  margin-top: 1.75rem;
}

.product-row {
  background: var(--wg-paper);
  border: 1px solid var(--wg-line);
  border-radius: var(--wg-radius-chip);
  margin: 0 0 0.75rem; /* also cancels Bootstrap's negative .row margins */
  padding: 1rem 0.5rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

/* pretix draws its row separators as a transparent border-top plus a 1px
   ::before line; with the card frame those became stray lines above and
   below every card. The row is flex now, so the clearfix is not needed. */
.item-category article.product-row {
  border: 1px solid var(--wg-line);
}

.item-category article.product-row::before,
.item-category article.product-row::after {
  display: none;
}

.product-row .product-description h4 {
  color: var(--wg-ink);
  font-family: var(--wg-sans);
  font-size: 1.3rem;
  font-weight: 700;
  margin: 0;
}

.product-row .price p {
  margin: 0;
  font-size: 1.9rem;
  line-height: 1;
}

.product-row .price small {
  display: block;
  font-size: 0.8rem;
  text-transform: none;
  letter-spacing: 0;
  margin-top: 0.25rem;
}

/* Quantity stepper: 44 px round buttons, thumb sized. */
.input-item-count-group {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.35rem;
}

.input-item-count-group .btn {
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 50%;
  border: 1.5px solid var(--wg-olive-deep);
  color: var(--wg-olive-deep);
  font-size: 1.35rem;
  font-weight: 700;
  line-height: 1;
  box-shadow: none;
  background: transparent;
}

.input-item-count-group .input-item-count {
  width: 3.25rem;
  height: 44px;
  border: 0;
  background: transparent;
  font-size: 1.25rem;
  padding: 0;
  -moz-appearance: textfield;
}

.input-item-count-group .input-item-count::-webkit-outer-spin-button,
.input-item-count-group .input-item-count::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* Main button: bigger and calmer. */
#btn-add-to-cart {
  min-height: 52px;
  font-size: 1.05rem;
  letter-spacing: 0.05em;
}

/* "Wenn Sie bereits ein Ticket bestellt haben": secondary, so it does not
   compete with the purchase. */
aside.front-page {
  margin-top: 2.5rem;
  padding: 1.25rem 1.25rem 0.5rem;
  background: var(--wg-cream-warm);
  border-radius: var(--wg-radius-chip);
}

aside.front-page h2 {
  font-size: 1.15rem;
}

aside.front-page p {
  color: var(--wg-muted);
  font-size: 0.95rem;
}

/* Start page list: rows as cards, labels in the palette instead of pretix
   blue. */
.event-list.alternating-rows > article.row,
.event-list.alternating-rows > article.row:nth-child(odd) {
  background: var(--wg-paper);
  border: 1px solid var(--wg-line);
  border-radius: var(--wg-radius-chip);
  margin: 0 0 0.6rem; /* cancels Bootstrap's negative .row margins */
  padding: 0.85rem 0.25rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

.event-list article.row h3 {
  font-size: 1.35rem;
  margin: 0;
}

.event-list article.row h3 a {
  color: var(--wg-ink);
}

.event-list article.row p {
  margin: 0;
}

main > .panel:has(.event-list) > .panel-heading {
  background: transparent;
  border: 0;
  padding-left: 0;
}

main > .panel:has(.event-list) {
  background: transparent;
  box-shadow: none;
}

main > .panel:has(.event-list) > .panel-body {
  padding: 0;
}

.textbubble-info,
.textbubble-success,
.textbubble-warning {
  background: var(--wg-olive-tint);
  color: var(--wg-olive-deep);
  border-radius: var(--wg-radius-pill);
  padding: 0.2em 0.75em;
  font-weight: 600;
}

.textbubble-danger {
  background: rgba(197, 33, 43, 0.1);
  color: var(--wg-red);
  border-radius: var(--wg-radius-pill);
  padding: 0.2em 0.75em;
}

/* Footer: one centred line. */
footer nav ul {
  justify-content: center;
}

@media (max-width: 767px) {
  body > header:not(:has(img))::before {
    height: 48px;
    margin-top: 0.75rem;
  }

  .main-box {
    padding: 1.25rem;
  }

  .page-header.logo-large {
    margin: -1.25rem -1.25rem 1.25rem;
  }

  .page-header.logo-large .event-logo {
    border-radius: var(--wg-radius-chip) var(--wg-radius-chip) 0 0;
  }

  .product-row .price p {
    font-size: 1.6rem;
  }

  .input-item-count-group {
    justify-content: flex-end;
  }
}
