/* ---------------------------------------------------------------------------
   Every colour, font and measurement below is a custom property set at runtime
   from config/theme.json. Nothing here should be a literal brand value — if
   you find yourself typing a hex code, add a theme key instead.
   --------------------------------------------------------------------------- */

:root {
  --color-background: #faf7f2;
  --color-surface: #ffffff;
  --color-text: #2e2a26;
  --color-muted: #8a8078;
  --color-accent: #9c6b4f;
  --color-accent-text: #ffffff;
  --color-border: #e6ded4;
  --color-danger: #b3453a;

  --font-heading: Georgia, "Times New Roman", serif;
  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-heading-weight: 500;
  --font-heading-spacing: 0.01em;
  --font-size-base: 17px;

  --radius: 10px;
  --max-width: 1080px;
  --space: 1rem;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  font-size: var(--font-size-base);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--color-background);
  color: var(--color-text);
  font-family: var(--font-body);
  line-height: 1.6;
  opacity: 0;
  transition: opacity 0.25s ease;
}

body.ready {
  opacity: 1;
}

h1,
h2,
h3 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  letter-spacing: var(--font-heading-spacing);
  line-height: 1.15;
  margin: 0 0 0.5em;
}

h1 {
  font-size: clamp(2.4rem, 8vw, 4.2rem);
}
h2 {
  font-size: clamp(1.6rem, 4vw, 2.2rem);
}
h3 {
  font-size: 1.2rem;
}

p {
  margin: 0 0 1em;
}

a {
  color: var(--color-accent);
}

img {
  max-width: 100%;
  display: block;
}

/* `hidden` has to keep meaning hidden. The browser hides it with
   `[hidden] { display: none }` in its own stylesheet, and a stylesheet like this
   one wins over the browser's whatever the specificity — so the rule above alone
   leaves every hidden <img> in the layout, invisible but still occupying its box
   and still catching the clicks. That is what covered the lightbox stage while a
   video was playing. */
img[hidden] {
  display: none;
}

/* --- layout ---------------------------------------------------------------- */

.page {
  min-height: 100vh;
}

.container {
  width: 100%;
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 calc(var(--space) * 1.25);
}

section.block {
  padding: calc(var(--space) * 3) 0;
}

section.block + section.block {
  border-top: 1px solid var(--color-border);
}

.section-title {
  text-align: center;
  margin-bottom: calc(var(--space) * 2);
}

.site-nav {
  display: flex;
  gap: calc(var(--space) * 1.5);
  justify-content: center;
  padding: var(--space) 0;
  font-size: 0.95rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--color-border);
  background: var(--color-surface);
  position: sticky;
  top: 0;
  z-index: 20;
}

.site-nav a {
  color: var(--color-muted);
  text-decoration: none;
}

.site-nav a.active,
.site-nav a:hover {
  color: var(--color-text);
}

/* --- hero ------------------------------------------------------------------ */

/* The band's height is the photograph's own: no crop, no minimum, and nothing
   printed on top of it. */
.hero-img {
  display: block;
  width: 100%;
  height: auto;
}


/* --- buttons --------------------------------------------------------------- */

.button {
  display: inline-block;
  border: 1px solid var(--color-accent);
  background: var(--color-accent);
  color: var(--color-accent-text);
  border-radius: var(--radius);
  padding: 0.7em 1.6em;
  font: inherit;
  font-size: 0.95rem;
  cursor: pointer;
  text-decoration: none;
  transition: filter 0.15s ease;
}

.button:hover:not(:disabled) {
  filter: brightness(0.92);
}

.button:disabled {
  opacity: 0.55;
  cursor: default;
}

.button.ghost {
  background: transparent;
  color: var(--color-accent);
}

.button.danger {
  background: var(--color-danger);
  border-color: var(--color-danger);
  color: #fff;
}

/* --- countdown ------------------------------------------------------------- */

/* The four units have to share one line on a phone: "secondi" is the widest
   label, so gap, unit width and both type sizes shrink with the viewport rather
   than letting it drop onto a second row. The upper end of every clamp is the
   desktop value, which is therefore unchanged. */
.countdown {
  display: flex;
  justify-content: center;
  gap: clamp(0.4rem, 3.5vw, calc(var(--space) * 1.5));
  flex-wrap: wrap;
}

.countdown-unit {
  min-width: clamp(3.4rem, 15vw, 4.5rem);
  text-align: center;
}

.countdown-value {
  font-family: var(--font-heading);
  font-size: clamp(1.7rem, 6vw, 3rem);
  line-height: 1;
}

.countdown-label {
  font-size: clamp(0.6rem, 2.6vw, 0.75rem);
  text-transform: uppercase;
  letter-spacing: clamp(0.06em, 0.5vw, 0.14em);
  color: var(--color-muted);
}

/* --- cards & grids --------------------------------------------------------- */

.card-grid {
  display: grid;
  gap: calc(var(--space) * 1.5);
  grid-template-columns: 1fr;
}

.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  overflow: hidden;
}

.card-body {
  padding: calc(var(--space) * 1.25);
}

.card img {
  width: 100%;
  height: 190px;
  object-fit: cover;
}

.card-role {
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-size: 0.72rem;
  color: var(--color-muted);
}

.card-address {
  color: var(--color-muted);
  font-size: 0.95rem;
}

/* --- timeline -------------------------------------------------------------- */

.timeline {
  list-style: none;
  margin: 0 auto;
  padding: 0;
  max-width: 620px;
}

.timeline li {
  display: grid;
  /* Fixed, and it has to be: every <li> is its own grid, so a content-based
     width is measured per row — "19:00 circa" would get a wider column than
     "17:00" and the titles would no longer line up. 6rem holds the longest
     label a programme normally has ("19:00 circa" measures ~5.4rem) without
     wrapping; widen this if you add a longer one. */
  grid-template-columns: 6rem 1fr;
  gap: var(--space);
  padding: calc(var(--space) * 1.1) 0;
  border-bottom: 1px solid var(--color-border);
}

.timeline li:last-child {
  border-bottom: none;
}

.timeline-time {
  font-family: var(--font-heading);
  font-size: 1.1rem;
  color: var(--color-accent);
}

.timeline-title {
  font-weight: 600;
}

.timeline-icon {
  margin-right: 0.45em;
}

.timeline-desc {
  color: var(--color-muted);
  font-size: 0.95rem;
}

/* --- info sections & faq ---------------------------------------------------- */

.info-blocks {
  display: grid;
  gap: calc(var(--space) * 1.5);
  grid-template-columns: 1fr;
}

.info-block {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: calc(var(--space) * 1.5);
}

.info-block p:last-child {
  margin-bottom: 0;
}

.info-block.layout-image {
  padding: 0;
  overflow: hidden;
}

.info-block.layout-image .info-body {
  padding: calc(var(--space) * 1.5);
}

.faq-list {
  max-width: 720px;
  margin: 0 auto;
}

.faq-item {
  border-bottom: 1px solid var(--color-border);
  padding: calc(var(--space) * 0.9) 0;
}

.faq-item summary {
  cursor: pointer;
  font-weight: 600;
  list-style: none;
}

.faq-item summary::-webkit-details-marker {
  display: none;
}

.faq-item summary::after {
  content: "+";
  float: right;
  color: var(--color-accent);
}

.faq-item[open] summary::after {
  content: "–";
}

.faq-item p {
  margin: 0.6em 0 0;
  color: var(--color-muted);
}

/* Intro above the contact cards. `pre-line` so a single line break in
   site.json is a line break on the page, and a blank line still starts a new
   paragraph. */
.contacts-intro {
  text-align: center;
  color: var(--color-muted);
  /* The longest of the two sentences needs ~25rem, so this leaves each of them
     a line of its own on a laptop; on a phone they wrap normally. */
  max-width: 46ch;
  margin: 0 auto calc(var(--space) * 1.5);
  white-space: pre-line;
}

.contacts-intro p:last-child {
  margin-bottom: 0;
}

.contact-list {
  display: grid;
  gap: var(--space);
  grid-template-columns: 1fr;
  max-width: 720px;
  margin: 0 auto;
  list-style: none;
  padding: 0;
}

.contact-list li {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: var(--space);
}

.contact-label {
  color: var(--color-muted);
  font-size: 0.85rem;
}

/* --- gallery cta ------------------------------------------------------------ */

.gallery-cta {
  text-align: center;
}

.gallery-cta p {
  color: var(--color-muted);
  max-width: 40ch;
  margin: 0 auto 1.5em;
}

/* --- footer ----------------------------------------------------------------- */

.site-footer {
  text-align: center;
  padding: calc(var(--space) * 3) var(--space);
  color: var(--color-muted);
  border-top: 1px solid var(--color-border);
  font-size: 0.9rem;
}

.site-footer .names {
  font-family: var(--font-heading);
  font-size: 1.4rem;
  color: var(--color-text);
  margin-bottom: 0.3em;
}

/* The footer text can be several paragraphs; the last one must not add space
   on top of the footer's own padding. */
.site-footer .footer-text p:last-child {
  margin-bottom: 0;
}

/* --- uploader --------------------------------------------------------------- */

.uploader {
  max-width: 620px;
  margin: 0 auto calc(var(--space) * 2);
}

.dropzone {
  border: 2px dashed var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
  padding: calc(var(--space) * 2.5) var(--space);
  text-align: center;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.dropzone:hover,
.dropzone.dragover {
  border-color: var(--color-accent);
}

.dropzone-title {
  font-size: 1.05rem;
  margin-bottom: 0.3em;
}

.dropzone-hint {
  color: var(--color-muted);
  font-size: 0.88rem;
}

.name-field {
  display: block;
  margin-top: var(--space);
}

.name-field span {
  display: block;
  font-size: 0.85rem;
  color: var(--color-muted);
  margin-bottom: 0.3em;
}

.name-field input {
  width: 100%;
  font: inherit;
  padding: 0.65em 0.8em;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
  color: inherit;
}

.name-field input:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}

.queue {
  list-style: none;
  margin: var(--space) 0 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}

.queue-item {
  display: grid;
  grid-template-columns: 44px 1fr auto;
  align-items: center;
  gap: 0.75rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 0.5rem 0.75rem;
  font-size: 0.9rem;
}

.queue-item img {
  width: 44px;
  height: 44px;
  object-fit: cover;
  border-radius: calc(var(--radius) / 2);
}

.queue-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.queue-status {
  color: var(--color-muted);
  font-size: 0.82rem;
  white-space: nowrap;
}

.queue-item.error .queue-status {
  color: var(--color-danger);
}

.progress {
  grid-column: 1 / -1;
  height: 3px;
  background: var(--color-border);
  border-radius: 2px;
  overflow: hidden;
}

.progress span {
  display: block;
  height: 100%;
  width: 0;
  background: var(--color-accent);
  transition: width 0.2s ease;
}

/* --- photo wall -------------------------------------------------------------- */

.wall-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space);
  margin-bottom: var(--space);
  flex-wrap: wrap;
}

.wall-count {
  color: var(--color-muted);
  font-size: 0.9rem;
}

.live-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--color-muted);
}

.live-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-muted);
}

.live-badge.online .live-dot {
  background: var(--color-accent);
  animation: pulse 2s ease-in-out infinite;
}

@keyframes pulse {
  50% {
    opacity: 0.35;
  }
}

.wall {
  column-count: var(--wall-columns, 2);
  column-gap: 0.6rem;
}

.wall-item {
  break-inside: avoid;
  margin-bottom: 0.6rem;
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  cursor: zoom-in;
  animation: fade-in 0.4s ease both;
}

.wall-item img {
  width: 100%;
  height: auto;
}

.wall-item .uploader-name {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 1.6em 0.6em 0.5em;
  font-size: 0.78rem;
  color: #fff;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.6), transparent);
  pointer-events: none;
}

.wall-item .admin-delete {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
  border: none;
  border-radius: calc(var(--radius) / 2);
  background: var(--color-danger);
  color: #fff;
  font: inherit;
  font-size: 0.78rem;
  padding: 0.25em 0.7em;
  cursor: pointer;
}

@keyframes fade-in {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }
}

.empty-state,
.list-end {
  text-align: center;
  color: var(--color-muted);
  padding: calc(var(--space) * 2) 0;
}

/* --- lightbox ---------------------------------------------------------------- */

.lightbox {
  position: fixed;
  inset: 0;
  /* Fully opaque: a translucent overlay lets the sticky nav and the tiles
     underneath bleed through, which reads as a rendering glitch. */
  background: #0b0b0b;
  display: grid;
  grid-template-rows: auto 1fr auto;
  z-index: 100;
  overscroll-behavior: contain;
}

.lightbox[hidden] {
  display: none;
}

.lightbox-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.75rem 1rem;
  color: #fff;
  font-size: 0.9rem;
  padding-top: max(0.75rem, env(safe-area-inset-top));
}

.lightbox-bar button,
.lightbox-bar a {
  background: none;
  border: none;
  color: #fff;
  font: inherit;
  cursor: pointer;
  text-decoration: none;
  opacity: 0.85;
}

/* The photo is positioned absolutely inside this box rather than laid out in
   flow. A percentage height on a grid item doesn't resolve when the row is
   `1fr` — the browser treats that height as indefinite and falls back to the
   image's intrinsic size, which overflowed and cropped the photo. An
   absolutely positioned child measures against this padding box, which is
   definite, so object-fit can letterbox correctly. */
.lightbox-stage {
  position: relative;
  overflow: hidden;
  min-height: 0;
}

.lightbox-stage img {
  position: absolute;
  top: 0.5rem;
  left: 0.5rem;
  width: calc(100% - 1rem);
  height: calc(100% - 1rem);
  object-fit: contain;
}

.lightbox-nav {
  display: flex;
  justify-content: space-between;
  padding: 1rem;
  padding-bottom: max(1rem, env(safe-area-inset-bottom));
}

.lightbox-nav button {
  background: rgba(255, 255, 255, 0.12);
  border: none;
  color: #fff;
  font: inherit;
  border-radius: var(--radius);
  padding: 0.6em 1.4em;
  cursor: pointer;
}

/* --- admin -------------------------------------------------------------------- */

.login-box {
  max-width: 340px;
  margin: 18vh auto;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: calc(var(--space) * 1.75);
}

.form-error {
  color: var(--color-danger);
  font-size: 0.88rem;
  min-height: 1.3em;
}

.toast {
  position: fixed;
  left: 50%;
  bottom: 1.5rem;
  transform: translateX(-50%);
  background: var(--color-text);
  color: var(--color-background);
  padding: 0.6em 1.2em;
  border-radius: var(--radius);
  font-size: 0.9rem;
  z-index: 200;
}

/* --- responsive ---------------------------------------------------------------- */

@media (min-width: 768px) {
  .card-grid,
  .info-blocks {
    grid-template-columns: repeat(2, 1fr);
  }

  .contact-list {
    grid-template-columns: repeat(2, 1fr);
  }

  .wall {
    column-count: var(--wall-columns-desktop, 4);
  }

  .queue-item {
    grid-template-columns: 44px 1fr auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* --- video ------------------------------------------------------------------- */

/* Play marker and duration on a poster frame — the only cue that a tile in the
   wall or in a post is a clip rather than a photo. */
.video-badge {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: grid;
  place-items: center;
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
  font-size: 0.9rem;
  padding-left: 0.15em;
  pointer-events: none;
}

.video-duration {
  position: absolute;
  top: 0.4rem;
  left: 0.4rem;
  padding: 0.1em 0.45em;
  border-radius: calc(var(--radius) / 2);
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}

/* A video in the upload queue has no still frame to preview yet. */
.queue-item.is-video img {
  background: var(--color-border);
  position: relative;
}

.queue-item.is-video img::after {
  content: '▶';
}

/* Centred the same way the photo is, and bounded by the stage rather than by the
   viewport: `80vh` ignored the bar above and the buttons below, so a vertical
   clip was both off-centre and taller than the space it had. The element keeps
   its own aspect ratio (no object-fit) so the controls stay glued to the bottom
   edge of the picture instead of floating at the bottom of a wider box. */
.lightbox-stage video {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  max-width: calc(100% - 1rem);
  max-height: calc(100% - 1rem);
  border-radius: var(--radius);
  background: #000;
}

/* --- bacheca ----------------------------------------------------------------- */

.container.narrow {
  max-width: min(640px, var(--max-width));
}

.composer {
  display: grid;
  gap: 0.75rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: calc(var(--space) * 1.1);
  margin-bottom: calc(var(--space) * 2);
}

.composer textarea {
  font: inherit;
  color: inherit;
  width: 100%;
  resize: vertical;
  min-height: 4.5rem;
  padding: 0.6em 0.7em;
  background: var(--color-background);
  border: 1px solid var(--color-border);
  border-radius: calc(var(--radius) / 1.5);
}

.composer textarea:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}

.composer-row {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
  justify-content: space-between;
}

.chips {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.chips:empty {
  display: none;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  max-width: 100%;
  padding: 0.25em 0.3em 0.25em 0.7em;
  font-size: 0.82rem;
  background: var(--color-background);
  border: 1px solid var(--color-border);
  border-radius: 999px;
}

.chip.is-video::before {
  content: '▶';
  font-size: 0.7em;
  color: var(--color-accent);
}

.chip-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 12rem;
}

.chip-remove {
  border: none;
  background: transparent;
  color: var(--color-muted);
  font: inherit;
  font-size: 1.1em;
  line-height: 1;
  cursor: pointer;
  padding: 0 0.3em;
}

.chip-remove:hover {
  color: var(--color-danger);
}

.feed {
  display: grid;
  gap: calc(var(--space) * 1.2);
}

.post {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: calc(var(--space) * 1.1);
  animation: fade-in 0.4s ease both;
}

.post-head {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  margin-bottom: 0.5rem;
}

.post-author {
  font-family: var(--font-heading);
  font-size: 1.05rem;
}

.post-when {
  color: var(--color-muted);
  font-size: 0.8rem;
  margin-right: auto;
}

.post-body p {
  margin: 0 0 0.5em;
  white-space: pre-line;
}

.post-body p:last-child {
  margin-bottom: 0;
}

/* One attachment fills the width; several tile into a square-ish grid. */
.post-media {
  display: grid;
  gap: 0.3rem;
  margin-top: 0.75rem;
}

.post-media[data-count='2'],
.post-media[data-count='3'],
.post-media[data-count='4'] {
  grid-template-columns: 1fr 1fr;
}

.post-media-item {
  position: relative;
  margin: 0;
  overflow: hidden;
  border-radius: calc(var(--radius) / 1.5);
  background: var(--color-background);
  cursor: zoom-in;
}

.post-media-item img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.post-media[data-count='1'] .post-media-item img {
  max-height: 70vh;
  object-fit: contain;
}

.post-media:not([data-count='1']) .post-media-item {
  aspect-ratio: 1;
}

.post .admin-delete {
  border: none;
  border-radius: calc(var(--radius) / 2);
  background: var(--color-danger);
  color: #fff;
  font: inherit;
  font-size: 0.78rem;
  padding: 0.25em 0.7em;
  cursor: pointer;
}

.admin-section-title {
  margin: calc(var(--space) * 2) 0 var(--space);
  color: var(--color-muted);
  font-size: 0.95rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* --- admin: the two bulk actions ------------------------------------------- */

.bulk-tools {
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
  padding: calc(var(--space) * 1.25);
}

.bulk-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space);
}

.bulk-hint {
  margin: 0.8em 0 0;
  color: var(--color-muted);
  font-size: 0.88rem;
}

/* `disabled` does nothing to an <a>, and the download button is one: it has to
   be a real link so the browser saves the stream instead of holding it. */
.button.disabled {
  opacity: 0.55;
  cursor: default;
  pointer-events: none;
}

/* Deliberately loud: this box is the last thing between a click and an empty
   wall, so it doesn't look like the rest of the furniture. */
.bulk-confirm {
  margin-top: var(--space);
  border: 1px solid var(--color-danger);
  border-radius: var(--radius);
  padding: var(--space);
}

.bulk-confirm h4 {
  margin: 0 0 0.5em;
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 1.15rem;
  color: var(--color-danger);
}

.bulk-confirm p {
  margin: 0 0 0.5em;
}

.bulk-confirm .bulk-actions {
  margin-top: var(--space);
}

/* An error slot with nothing in it shouldn't hold a gap open in the composer. */
.form-error:empty {
  display: none;
}

/* --- info blocks: un blocco solo ------------------------------------------- */

/* Two-up is right for a pair of short blocks (dress code, parking); a block
   placed on its own with "section:<id>" should have the whole row. */
.info-blocks.single {
  grid-template-columns: 1fr;
}

/* Prose in a text-only block: a measure that stays readable at 1080px, centred
   in the card so a long intro doesn't sit lopsided on a wide screen. */
.info-block.layout-text > div {
  max-width: 64ch;
  margin-inline: auto;
}

/* layout: "plain" — dressed like the schedule: no card, and the same centred
   column width, so the two sections read as one family. */
.info-block.layout-plain {
  background: none;
  border: 0;
  padding: 0;
}

.info-block.layout-plain > div {
  max-width: 620px;
  margin-inline: auto;
}
