/* ---------------------------------------------------------------------
   Design tokens
   Palette: cool paper background, deep indigo primary, warm amber used
   only for the progress signature -- kept out of status colors so it
   never gets confused with "OK / maybe / not available".
--------------------------------------------------------------------- */
:root {
  --bg: #F7F4F1;
  --surface: #FFFFFF;
  --ink: #2A2230;
  --muted: #6F6472;
  --border: #E8E1E4;

  --primary: #503D4D;
  --primary-ink: #FFFFFF;
  --primary-soft: #EFE7EC;

  --accent: #F26F2A;
  --tertiary: #F6BD2D;

  --yes-bg: #DCFCE7;   --yes-ink: #166534;   --yes-border: #86EFAC;
  --maybe-bg: #FEF3C7;  --maybe-ink: #92400E; --maybe-border: #FDE68A;
  --no-bg: #FEE2E2;    --no-ink: #991B1B;    --no-border: #FCA5A5;
  --blank-bg: #F3F4F6; --blank-ink: #9CA3AF; --blank-border: #E5E7EB;

  --font-body: Merriweather, Georgia, serif;
  --font-heading: "Merriweather Sans", -apple-system, "Segoe UI", Roboto, sans-serif;
  --radius-sm: 8px;
  --radius-md: 14px;
  --radius-lg: 20px;
  --radius-pill: 999px;

  /* Alto del aviso de beta. Lo usan el propio aviso, el hueco que le deja
     el body, el `top` de la cabecera pegajosa y el del indicador de
     recargar: si se cambia aqui, los cuatro se mueven juntos. */
  --beta-bar: 1.5rem;

  /* Alto de los botones grandes de la home y, por lo tanto, de la tira de
     una oferta: las imagenes se dibujan para este alto y sangran por
     arriba y por abajo. Los dos lo leen de aqui para que no puedan
     separarse. */
  --tool-btn: 92px;
}

html { background: var(--bg); }
body {
  margin: 0; -webkit-tap-highlight-color: transparent;
  padding-top: calc(var(--beta-bar) + env(safe-area-inset-top));
  padding-bottom: env(safe-area-inset-bottom);
}
button, .chip, .slot-cell, a.avail-btn { touch-action: manipulation; }
/* `hidden` lo pone la hoja del navegador con `display: none` sin
   especificidad ninguna, asi que cualquier regla de clase de aqui que fije
   `display` lo anula y el elemento se ve igual. Pasa con .cta-card, con
   .avail-btn y con .save-state: los tres arrancan ocultos. */
[hidden] { display: none !important; }
input, textarea, select { font-size: 16px; } /* prevents iOS Safari/WebView auto-zoom on focus */

.avail-wrap {
  max-width: 720px;
  margin: 0 auto;
  padding: 1.25rem 1rem 2rem;
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--bg);
}
.avail-wrap h1 {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 1.65rem;
  letter-spacing: -.01em;
  margin: 0 0 .25rem;
}
.avail-wrap h3 { font-size: 1.05rem; margin: 0 0 .5rem; }
.avail-wrap .muted { color: var(--muted); font-size: .88rem; }

.avail-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: 1.25rem; margin-bottom: 1.25rem;
}

.avail-wrap label { display: block; font-weight: 600; font-size: .85rem; margin: .5rem 0 .3rem; }
.avail-wrap input[type=text], .avail-wrap input[type=number],
.avail-wrap input[type=date], .avail-wrap input[type=time],
.avail-wrap textarea, .avail-wrap select {
  width: 100%; padding: .75rem .8rem; border: 1.5px solid var(--border); border-radius: var(--radius-sm);
  font: 500 1rem 'Inter', sans-serif; box-sizing: border-box; color: var(--ink);
  min-height: 48px;
}
.avail-wrap input:focus, .avail-wrap textarea:focus, .avail-wrap select:focus,
/* Sin esto un boton deshabilitado se ve exactamente igual que uno vivo:
   el de la pagina de mantenimiento arranca apagado un minuto. */
.avail-btn:disabled { opacity: .55; cursor: default; }

.chip:focus-visible, .avail-btn:focus-visible {
  outline: 2.5px solid var(--primary); outline-offset: 2px;
}

.avail-btn {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--primary); color: var(--primary-ink); border: none;
  padding: .75rem 1.1rem; border-radius: var(--radius-sm); cursor: pointer;
  font: 600 .95rem 'Inter', sans-serif; text-decoration: none; min-height: 48px;
  transition: transform .1s ease, opacity .15s ease;
  /* Sin esto un `width: 100%` suma los 2.2rem de padding y el boton sale
     por la derecha de la pantalla; hay varios asi. */
  box-sizing: border-box;
}
.avail-btn.secondary { background: var(--primary-soft); color: var(--primary); }
.avail-btn.small { padding: .5rem .8rem; font-size: .82rem; min-height: 40px; }
.avail-btn:active { transform: scale(.97); }
.avail-btn:hover { opacity: .92; }

.avail-msg { padding: .7rem 1rem; border-radius: var(--radius-sm); margin-bottom: 1rem; font-size: .9rem; font-weight: 500; }
.avail-msg.success { background: var(--yes-bg); color: var(--yes-ink); }
.avail-msg.info { background: #EFF3FF; color: #263691; }
.avail-msg.warning { background: var(--maybe-bg); color: var(--maybe-ink); }
.avail-msg.error { background: var(--no-bg); color: #7f1d1d; }

/* ---------------------------------------------------------------------
   Sticky header + live progress (respondent view)
--------------------------------------------------------------------- */
.resp-sticky-header {
  position: sticky; top: calc(var(--beta-bar) + env(safe-area-inset-top)); z-index: 20;
  background: var(--bg);
  padding: .75rem 0 .6rem;
  margin: 0 0 .75rem;
  border-bottom: 1px solid var(--border);
}
.resp-sticky-header h1 { font-size: 1.3rem; }
.back-link { display: inline-block; font-size: .82rem; font-weight: 600; color: var(--primary); text-decoration: none; margin-bottom: .3rem; }
.progress-track {
  background: var(--border); border-radius: var(--radius-pill); height: 8px; overflow: hidden; margin-top: .6rem;
}
.progress-fill { background: var(--accent); height: 100%; border-radius: var(--radius-pill); transition: width .25s ease; width: 0%; }
.progress-label { font-size: .78rem; color: var(--muted); margin-top: .35rem; font-weight: 600; }

/* ---------------------------------------------------------------------
   Attendants stepper
--------------------------------------------------------------------- */
.stepper { display: flex; align-items: center; gap: 1rem; margin-top: .3rem; }
.stepper button {
  width: 46px; height: 46px; border-radius: 50%; border: 1.5px solid var(--border);
  background: var(--surface); font-size: 1.4rem; font-weight: 700; color: var(--primary);
  cursor: pointer; line-height: 1; display: flex; align-items: center; justify-content: center;
}
.stepper button:active { background: var(--primary-soft); }
.stepper .count { font: 700 1.25rem 'IBM Plex Mono', monospace; min-width: 2ch; text-align: center; }

/* ---------------------------------------------------------------------
   Bulk-paint toolbar (chip-based, touch-first)
--------------------------------------------------------------------- */
.bulk-toolbar { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 1rem; margin-bottom: 1rem; }
.bulk-section { margin-bottom: 1rem; }
.bulk-section:last-child { margin-bottom: 0; }
.bulk-section-label { font-weight: 700; font-size: .8rem; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); margin-bottom: .5rem; }
.chip-row { display: flex; flex-wrap: wrap; gap: .45rem; }
.chip {
  border: 1.5px solid var(--border); background: var(--surface); color: var(--ink);
  padding: .55rem 1rem; border-radius: var(--radius-pill); font: 600 .85rem 'Inter';
  cursor: pointer; min-height: 42px; transition: background .12s, border-color .12s, color .12s;
}
.chip.is-active { background: var(--primary); border-color: var(--primary); color: #fff; }

.status-row { display: flex; gap: .5rem; flex-wrap: wrap; }
.status-btn {
  flex: 1 1 0; min-width: 80px; border: none; border-radius: var(--radius-md);
  padding: .8rem .5rem; font: 700 .85rem 'Inter'; cursor: pointer; color: #fff; min-height: 48px;
}
.status-btn.yes { background: #16A34A; }
.status-btn.maybe { background: #D97706; }
.status-btn.no { background: #DC2626; }
.status-btn.clear { background: var(--surface); color: var(--muted); border: 1.5px solid var(--border); }

/* ---------------------------------------------------------------------
   Response grid
--------------------------------------------------------------------- */
.legend { display: flex; gap: 1rem; flex-wrap: wrap; font-size: .78rem; margin-bottom: .75rem; color: var(--muted); }
.legend span { display: inline-flex; align-items: center; gap: .35rem; font-weight: 600; }
.legend i { width: 12px; height: 12px; border-radius: 4px; display: inline-block; }

.resp-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); }
.resp-table { width: 100%; border-collapse: collapse; font-size: .85rem; }
.resp-table th, .resp-table td { border-bottom: 1px solid var(--border); padding: .5rem; text-align: center; }
.resp-table thead th {
  position: sticky; top: 0; background: #FAFAFC; z-index: 2; font-size: .72rem;
  text-transform: uppercase; letter-spacing: .03em; color: var(--muted); padding: .65rem .5rem;
}
.resp-table th:first-child, .resp-table td.date-cell {
  text-align: left; position: sticky; left: 0; background: var(--surface); z-index: 3;
  box-shadow: 1px 0 0 var(--border);
}
.date-cell .wd { display: block; font: 600 .68rem 'Inter'; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; }
.date-cell .day { display: block; font: 700 1.05rem 'IBM Plex Mono', monospace; }

.slot-cell {
  cursor: pointer; user-select: none; border-radius: var(--radius-sm); padding: .7rem .3rem;
  font: 700 1.1rem 'Inter'; min-width: 56px; min-height: 44px;
  background: var(--blank-bg); color: var(--blank-ink); border: 1.5px solid var(--blank-border);
  display: flex; align-items: center; justify-content: center;
}
.slot-cell[data-status="yes"] { background: var(--yes-bg); color: var(--yes-ink); border-color: var(--yes-border); }
.slot-cell[data-status="maybe"] { background: var(--maybe-bg); color: var(--maybe-ink); border-color: var(--maybe-border); }
.slot-cell[data-status="no"] { background: var(--no-bg); color: var(--no-ink); border-color: var(--no-border); }

/* Sticky bottom save bar */
.sticky-actionbar {
  position: sticky; bottom: 0; z-index: 20;
  background: linear-gradient(to top, var(--bg) 65%, transparent);
  padding: 1rem 0 calc(.75rem + env(safe-area-inset-bottom));
  margin-top: .5rem;
}
.sticky-actionbar .avail-btn {
  width: 100%; font-size: 1rem; padding: 1rem;
  box-shadow: 0 6px 18px rgba(55, 48, 163, .3);
}

/* ---------------------------------------------------------------------
   Event list (app home screen)
--------------------------------------------------------------------- */
.list-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 1rem;
}
.list-header h1 { margin: 0; }

.event-card {
  display: flex; align-items: center; gap: .75rem;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: 1rem 1.1rem; margin-bottom: .75rem; text-decoration: none; color: var(--ink);
  position: relative; min-height: 48px;
}
.event-card:active { background: var(--primary-soft); }
.event-card-main { flex: 1; min-width: 0; }
.event-card-name { font-weight: 700; font-size: 1.02rem; }
.event-card-dates { font-size: .82rem; margin-top: .15rem; }

/* En su propia linea bajo el nombre y no a la derecha: a 390px, con
   miniatura y una etiqueta larga, el nombre se quedaba en tres lineas de
   dos palabras. */
.status-badge {
  display: inline-block; margin-top: .45rem;
  font: 700 .78rem 'Inter'; padding: .4rem .7rem; border-radius: var(--radius-pill);
  white-space: nowrap;
}
.status-badge.status-not_started { background: var(--blank-bg); color: var(--muted); }
.status-badge.status-in_progress { background: #FEF3C7; color: #92400E; }
.status-badge.status-done { background: var(--yes-bg); color: var(--yes-ink); }
.status-badge.status-interested { background: var(--surface); color: var(--primary); box-shadow: inset 0 0 0 1px var(--primary); }

.closed-tag {
  position: absolute; top: -8px; right: 12px;
  background: var(--muted); color: #fff; font: 700 .68rem 'Inter';
  padding: .15rem .5rem; border-radius: var(--radius-pill);
}

/* «Novedad» y «Nuevas fechas»: las pinta el servidor por fecha, y news.js
   las retira en el movil que ya abrio esa preinscripcion. */
.news-tags {
  position: absolute; top: -8px; left: 12px; display: flex; gap: .3rem;
}
.news-tag {
  background: var(--primary); color: #fff; font: 700 .68rem 'Inter';
  padding: .15rem .5rem; border-radius: var(--radius-pill);
}

/* Etiquetas de la actividad, en la tarjeta y dentro de la preinscripcion.
   No son las del filtro de la lista: aquellas son enlaces con estado
   seleccionado y viven en el <style> de esa pagina. */
.tag-pill-row { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .35rem; }
.tag-pill {
  font: 600 .72rem var(--font-heading); padding: .2rem .55rem;
  border-radius: var(--radius-pill);
  background: var(--primary-soft); color: var(--primary);
}

/* ---------------------------------------------------------------------
   Organizer pages (pattern grid, matrix) -- unchanged structurally,
   just inherits the refreshed base tokens above.
--------------------------------------------------------------------- */
.pattern-table { width: 100%; border-collapse: collapse; font-size: .9rem; }
.pattern-table th, .pattern-table td { border: 1px solid var(--border); padding: .4rem .5rem; text-align: center; }
.pattern-table th:first-child, .pattern-table td:first-child { text-align: left; }
.pattern-toolbar { display: flex; gap: .5rem; flex-wrap: wrap; margin-bottom: .75rem; }

.matrix-scroll { overflow: auto; max-height: 75vh; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.matrix-table { border-collapse: collapse; font-size: .78rem; white-space: nowrap; }
.matrix-table th, .matrix-table td { border: 1px solid var(--border); padding: .3rem .5rem; text-align: center; }
.matrix-table thead th { position: sticky; top: 0; background: #f9fafb; z-index: 3; }
.matrix-table tbody th, .matrix-table tbody td.row-head { position: sticky; left: 0; background: #fff; z-index: 2; text-align: left; }
.matrix-table thead th:first-child, .matrix-table tbody td.row-head { z-index: 4; box-shadow: 1px 0 0 var(--border); }
.matrix-cell { font-weight: 700; }
.matrix-cell.yes { background: var(--yes-bg); color: var(--yes-ink); }
.matrix-cell.maybe { background: var(--maybe-bg); color: var(--maybe-ink); }
.matrix-cell.no { background: var(--no-bg); color: var(--no-ink); }
.matrix-cell.blank { background: #fafafa; color: #d1d5db; }
.matrix-table .score-col { font-weight: 700; background: var(--primary-soft); }
.matrix-table tr.top-row td.row-head { background: #fffbeb; }
.matrix-toolbar { display: flex; gap: .75rem; align-items: center; margin-bottom: .75rem; font-size: .85rem; }

/* Marca: cuerpo en Merriweather, igual que mamarrachine.org. Los controles
   van en la sans porque el grid baja a 12px y la serif se emborrona ahí. */
button, .avail-btn, .chip, .slot-cell, input, textarea, select,
.avail-wrap h1, .avail-wrap h2, .avail-wrap h3, .avail-wrap h4 {
  font-family: var(--font-heading);
}

/* ---------------------------------------------------------------------
   Ayuda contextual: boton "?" + modal. Vive aqui y no en cada plantilla
   porque ya son tres las pantallas que lo usan.
--------------------------------------------------------------------- */
.help-btn {
  flex: 0 0 auto; width: 44px; height: 44px; padding: 7px;
  border: none; background: none; cursor: pointer;
}
.help-btn > span {
  display: grid; place-items: center; width: 30px; height: 30px;
  border-radius: 50%; border: 1px solid var(--border); background: var(--surface);
  color: var(--muted); font-weight: 700; font-size: .9rem;
}
.help-modal {
  border: none; border-radius: var(--radius-lg); padding: 1.25rem;
  max-width: 20rem; width: calc(100% - 2.5rem);
  background: var(--surface); color: var(--ink);
}
.help-modal::backdrop { background: rgba(15, 23, 42, .45); }
.help-modal h3 { margin: 0 0 .5rem; font-size: 1.05rem; }
.help-modal p { margin: 0 0 1rem; font-size: .9rem; color: var(--muted); line-height: 1.45; }

/* ---------------------------------------------------------------------
   Aviso de beta. Generado desde CSS y no como marcado en cada plantilla:
   las pantallas de cliente no comparten base, asi que este es el unico
   sitio donde ponerlo (y quitarlo) una sola vez. Solo lo cargan ellas --
   base_staff.html enlaza staff.css, no este fichero.

   Una banda entera y no un triangulo en la esquina: en un movil la
   esquina cae justo encima del titulo o del boton de ayuda de casi todas
   las pantallas, y tapaba texto que si hace falta leer.
--------------------------------------------------------------------- */
body::before {
  content: "BETA \2014  estamos probando la app";
  position: fixed; top: 0; left: 0; right: 0; z-index: 60; pointer-events: none;
  height: var(--beta-bar); padding-top: env(safe-area-inset-top);
  display: grid; place-items: center;
  background: var(--tertiary); color: var(--ink);
  font: 700 .68rem var(--font-heading); letter-spacing: .06em;
}

/* ---------------------------------------------------------------------
   Miniatura de la actividad en la lista de preinscripciones
--------------------------------------------------------------------- */
.event-card-thumb {
  width: 56px; height: 56px; flex-shrink: 0;
  object-fit: cover; border-radius: var(--radius-md);
  background: var(--blank-bg);
}


/* ---------------------------------------------------------------------
   Opciones avanzadas (rejilla de respuesta). Cerrado por defecto: pintar
   por bloques y responder por varias personas son la excepcion, y tenerlo
   todo desplegado hacia que la pantalla empezara por lo complicado.
--------------------------------------------------------------------- */
.advanced {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); margin-bottom: 1rem;
}
.advanced > summary {
  list-style: none; cursor: pointer; padding: .9rem 1rem; min-height: 48px;
  display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  font: 600 .9rem var(--font-heading); color: var(--primary);
}
.advanced > summary::-webkit-details-marker { display: none; }
.advanced > summary::after { content: "▾"; font-size: .9rem; }
.advanced[open] > summary::after { content: "▴"; }
.advanced > summary + * { padding: 0 1rem 1rem; }
.advanced .bulk-toolbar { border: none; padding: 0; margin: 0; background: none; }

/* ---------------------------------------------------------------------
   Estado del autoguardado (sustituye al boton de guardar cuando hay JS)
--------------------------------------------------------------------- */
.save-state {
  display: flex; align-items: center; justify-content: center; gap: .5rem;
  min-height: 48px; padding: .75rem 1rem; border-radius: var(--radius-sm);
  font: 600 .9rem var(--font-heading);
  background: var(--surface); border: 1px solid var(--border); color: var(--muted);
}
.save-state[data-state="saved"] { background: var(--yes-bg); border-color: var(--yes-border); color: var(--yes-ink); }
.save-state[data-state="failed"] { background: var(--no-bg); border-color: var(--no-border); color: var(--no-ink); }
.save-state button {
  border: none; background: var(--no-ink); color: #fff; cursor: pointer;
  border-radius: var(--radius-pill); padding: .35rem .8rem; font: 600 .8rem var(--font-heading);
}

/* ---------------------------------------------------------------------
   Navegación del backoffice de preinscripciones. Vive aquí, y no en
   staff.css, porque estas cuatro páginas usan style.css y no extienden
   base_staff.html como el resto del panel -- ver server/TODO.md.
--------------------------------------------------------------------- */
.staff-nav {
  display: flex; flex-wrap: wrap; align-items: center; gap: .4rem;
  font: 600 .85rem var(--font-heading); margin-bottom: .9rem;
}
.staff-nav a { color: var(--primary); text-decoration: none; }
.staff-nav a:hover { text-decoration: underline; }
.staff-nav span { color: var(--muted); font-weight: 400; }
.staff-nav-here { color: var(--muted); }

.staff-tabs { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: 1.25rem; }
.staff-tabs a {
  min-height: 44px; display: inline-flex; align-items: center; padding: 0 1rem;
  border: 1px solid var(--border); border-radius: var(--radius-pill);
  background: var(--surface); color: var(--ink); text-decoration: none;
  font: 600 .85rem var(--font-heading);
}
.staff-tabs a.is-here {
  background: var(--primary); border-color: var(--primary); color: var(--primary-ink);
}

/* ---------------------------------------------------------------------
   Botones grandes de navegacion (home) y rejilla de la pantalla Personal.
   Viven aqui y no en el <style> de la home porque los comparten tres
   pantallas y una oferta tiene que medir exactamente lo que ellos.
--------------------------------------------------------------------- */
.tool-btn {
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: .4rem;
  /* Sin esto la altura fija de abajo es la del contenido y el boton acaba
     midiendo 127px con sus 2.2rem de padding y sus dos bordes: la tira de
     una oferta, que no tiene ni padding ni borde, se quedaba 35px mas baja
     que el boton al que tiene que igualar. */
  box-sizing: border-box;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 1.1rem .5rem; text-decoration: none; color: var(--ink);
  min-height: 44px;
}
.tool-btn:active { background: var(--primary-soft); }
.tool-icon { font-size: 1.6rem; }
.tool-label { font-weight: 600; font-size: .88rem; }
.tool-note { font-size: .7rem; color: var(--muted); text-align: center; }
.tool-btn.is-locked { opacity: .55; cursor: default; }

.tools-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: .75rem;
  margin-bottom: 1.25rem;
}

/* Un grupo por fila, bajo la rejilla de Personal: mismo material que un
   `.tool-btn`, pero tumbado, porque lo que importa es el nombre y lo que
   toca después, que no caben en media columna. */
.group-btn {
  display: flex; align-items: center; gap: .8rem;
  box-sizing: border-box; width: 100%; min-height: 64px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: .8rem 1rem; margin-bottom: .75rem;
  text-decoration: none; color: var(--ink);
}
.group-btn:active { background: var(--primary-soft); }
.group-btn .tool-icon { flex: none; }
.group-btn-text { display: flex; flex-direction: column; gap: .15rem; flex: 1; min-width: 0; }
.group-btn-status { font-size: .8rem; color: var(--muted); }
.group-btn-chevron { flex: none; color: var(--muted); font-size: 1.2rem; }

.tool-slot { position: relative; display: grid; margin-bottom: .75rem; }
.tool-slot > .help-btn { position: absolute; top: 0; right: 0; }
/* Alto fijo, no minimo: es lo que hace que la tira de una oferta y estos
   botones se vean del mismo tamano. En la rejilla de Personal se deja
   crecer, que ahi hay una linea mas de nota. */
.tool-slot > .tool-btn { height: var(--tool-btn); }

/* La tira es un <a> cuando lleva a un enlace y un <button> cuando abre el
   modal: sin el reseteo, el boton hereda borde, fondo y padding del
   navegador y la tira deja de medir lo que miden los botones de la home. */
.promo {
  display: block; width: 100%; box-sizing: border-box; padding: 0;
  border: none; background: none; font: inherit; cursor: pointer;
  margin-bottom: .75rem; border-radius: var(--radius-lg); overflow: hidden;
}
.promo img {
  display: block; width: 100%; height: var(--tool-btn);
  object-fit: cover; object-position: center;
}

/* Modal de una oferta: mas ancho que el de ayuda porque lleva un texto
   entero, y con tope de alto para que una explicacion larga scrolee
   dentro en vez de salirse por abajo de la pantalla. */
/* `box-sizing` aparte: `.help-modal` mide con `calc(100% - 2.5rem)` y en
   content-box los 2.5rem se los come el padding, asi que el modal salia
   pegado a los dos bordes de la pantalla. */
.promo-modal {
  box-sizing: border-box; max-width: 24rem; max-height: 80vh; overflow-y: auto;
}
.promo-modal .avail-btn { width: 100%; margin-top: .5rem; }
.promo-text { font-size: .92rem; line-height: 1.5; }
.promo-text h3, .promo-text h4, .promo-text h5 {
  margin: 1rem 0 .35rem; font-family: var(--font-heading);
}
.promo-text > :first-child { margin-top: 0; }
.promo-text h3 { font-size: 1.05rem; }
.promo-text h4 { font-size: .95rem; }
.promo-text h5 { font-size: .9rem; }
/* `.help-modal p` pinta el cuerpo en gris apagado, que vale para dos
   lineas de ayuda y no para una explicacion entera. */
.promo-text p { margin: 0 0 .7rem; color: var(--ink); }
.promo-text ul, .promo-text ol { margin: 0 0 .7rem; padding-left: 1.2rem; }
.promo-text li { margin-bottom: .25rem; }
.promo-text a { color: var(--primary); }

/* El pie con el enlace a la politica, en las pantallas que recogen datos.
   Va en `style.css` y no en cada plantilla porque son cinco. */
.privacy-note {
  margin: 1.5rem 0 .5rem; font-size: .78rem; line-height: 1.45;
  color: var(--muted); text-align: center;
}
.privacy-note a { color: var(--muted); text-decoration: underline; }

/* El codigo de un cupon: se lee en voz alta a un metro de distancia y en
   un movil al sol, asi que va grande, espaciado y en monoespaciada. */
.code-card { text-align: center; }
.code-lead { font-weight: 700; margin: 0 0 .6rem; }
.code {
  font: 700 2.4rem/1.1 'IBM Plex Mono', monospace;
  letter-spacing: .18em; margin: 0 0 .6rem; color: var(--primary);
  word-break: break-all;
}

/* La frase de por que un cupon esta deshabilitado. Va bajo su boton, no
   sobre la tira: la tira es la imagen del negocio y no se pinta encima. */
.promo-locked {
  margin: .4rem 0 0; font-size: .78rem; line-height: 1.4;
  color: var(--muted); text-align: center;
}

/* Casilla + texto de una fila de consentimiento. `align-items: start` y no
   center: con dos lineas de texto, centrado deja la casilla flotando. */
.consent-row { display: flex; gap: .6rem; align-items: start; font-size: .92rem; }
.consent-row input[type=checkbox] { width: 1.15rem; height: 1.15rem; margin-top: .1rem; flex: none; }

/* Interruptor. La casilla real sigue ahi debajo -- solo se saca de la
   vista, no se quita: `display:none` la deja fuera del formulario y del
   foco del teclado, y entonces deja de existir para quien no usa raton. */
/* `.avail-wrap .toggle-row` y no `.toggle-row` a secas: la hoja ya trae
   `.avail-wrap label { display: block }`, que con (0,1,1) le gana a una
   clase suelta y dejaba el interruptor sin flex -- pegado al texto y sin
   ir al margen derecho. Mismo agujero que `[hidden]`. */
.avail-wrap .toggle-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: .9rem; margin: 0; padding: .7rem 0;
  border-bottom: 1px solid var(--border);
  font-size: .92rem; font-weight: 400; cursor: pointer;
}
.avail-wrap .toggle-row:last-of-type { border-bottom: none; }
.avail-wrap .toggle-row input { position: absolute; opacity: 0; width: 0; height: 0; }
/* Apagado tiene que verse: `--border` sobre `--surface` es casi el mismo
   color y el interruptor desaparecia, asi que un control sin estado
   parecia texto suelto. Relleno gris de casilla vacia y borde encima. */
.toggle-track {
  flex: none; width: 46px; height: 28px; border-radius: var(--radius-pill);
  background: var(--blank-bg); border: 1px solid var(--blank-border);
  position: relative; transition: background .15s, border-color .15s;
}
.toggle-track::after {
  content: ""; position: absolute; top: 2px; left: 2px;
  width: 22px; height: 22px; border-radius: 50%; background: #fff;
  box-shadow: 0 1px 2px rgba(42, 34, 48, .35);
  transition: transform .15s;
}
.avail-wrap .toggle-row input:checked + .toggle-track {
  background: var(--primary); border-color: var(--primary);
}
.avail-wrap .toggle-row input:checked + .toggle-track::after { transform: translateX(18px); }
.avail-wrap .toggle-row input:focus-visible + .toggle-track { outline: 2px solid var(--ink); outline-offset: 2px; }
.avail-wrap .toggle-row input:disabled + .toggle-track { opacity: .45; }
.avail-wrap .toggle-row.is-disabled { cursor: default; color: var(--muted); }
.toggle-note { display: block; font-size: .78rem; color: var(--muted); }

/* ---------------------------------------------------------------------
   Tirar hacia abajo para recargar (pull-refresh.js, solo en la app)
--------------------------------------------------------------------- */
/* La clase la pone el script, y solo dentro de la app: en el navegador
   esto apagaria el gesto de recargar que el navegador ya trae. */
html.ptr-on, html.ptr-on body { overscroll-behavior-y: contain; }

/* Reposo es 52px por encima del aviso de beta, que tiene mas z-index y lo
   tapa: el indicador sale de debajo de la banda, no de la nada. */
.ptr-indicator {
  position: fixed; left: 50%; z-index: 55; pointer-events: none;
  top: calc(var(--beta-bar) + env(safe-area-inset-top));
  margin: -52px 0 0 -17px; width: 34px; height: 34px;
  display: grid; place-items: center;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 50%; box-shadow: 0 2px 10px rgba(42, 34, 48, .18);
  opacity: 0;
}
/* La transicion se enciende al soltar: mientras el dedo manda, el
   indicador tiene que ir pegado a el y no persiguiendolo. */
.ptr-indicator.ptr-settling { transition: transform .2s ease, opacity .2s ease; }

.ptr-arrow {
  width: 9px; height: 9px; margin-top: -3px;
  border: 2px solid var(--primary); border-top: 0; border-left: 0;
  transform: rotate(45deg); transition: transform .15s ease;
}
.ptr-ready .ptr-arrow { margin-top: 3px; transform: rotate(-135deg); }
.ptr-loading .ptr-arrow {
  width: 14px; height: 14px; margin: 0;
  border: 2px solid var(--border); border-top-color: var(--primary);
  border-radius: 50%; transform: none;
  animation: ptr-spin .7s linear infinite;
}
@keyframes ptr-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .ptr-indicator.ptr-settling, .ptr-arrow { transition: none; }
  .ptr-loading .ptr-arrow { animation: none; }
}


/* ---------------------------------------------------------------------
   Editor de imagen del panel (image-editor.js): recortar o estirar la
   imagen de una actividad antes de subirla.
   --------------------------------------------------------------------- */
.img-editor { margin: .5rem 0 .8rem; }
.img-editor-panel {
  border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: .8rem; margin: .5rem 0; background: var(--surface);
}
.img-editor-controls { display: flex; flex-wrap: wrap; gap: .5rem .9rem; align-items: center; margin-bottom: .7rem; }
.avail-wrap .img-editor-controls > label { display: inline; margin: 0; }
.img-editor-custom { display: inline-flex; gap: .35rem; align-items: center; }
.img-editor-custom input { width: 5.5rem; }
.img-editor-modes { display: inline-flex; gap: .8rem; }
.avail-wrap .img-editor-modes label,
.avail-wrap label.img-editor-zoom { display: inline-flex; align-items: center; gap: .35rem; margin: 0; }
.img-editor-stage {
  display: block; max-width: 100%; touch-action: none; cursor: move;
  border-radius: var(--radius-sm); background: var(--blank-bg);
}
.img-editor-result-head { font-weight: 600; font-size: .85rem; margin: .8rem 0 .3rem; }
.img-editor-result {
  display: block; max-width: 100%; max-height: 180px; width: auto; height: auto;
  border-radius: var(--radius-sm); border: 1px solid var(--border);
}
.img-editor-buttons { display: flex; gap: .5rem; margin-top: .6rem; }

/* Aviso a quien es de un grupo y abre una preinscripción de su actividad. */
.group-warning { box-sizing: border-box; max-width: 24rem; }
.group-warning p { color: var(--ink); }
.group-warning .avail-btn { display: block; width: 100%; margin-top: .5rem; text-align: center; }
/* Sin JS no llega a ser modal, y abierto sin más flota encima del texto. */
.group-warning[open]:not(:modal) {
  position: static; width: 100%; max-width: none; margin: 0 0 1rem;
  border: 1px solid var(--border);
}

/* Borrar una hoja desde la matriz. */
.sheet-actions { display: flex; gap: .25rem; justify-content: center; margin-top: .3rem; }
.sheet-actions button {
  font: 600 .7rem/1.2 inherit; padding: .2rem .5rem; cursor: pointer;
  border: 1px solid var(--border); border-radius: var(--radius-pill);
  background: var(--surface); color: var(--ink);
}
.sheet-actions .danger { color: #b91c1c; border-color: #b91c1c; }
.sheet-modal { box-sizing: border-box; max-width: 26rem; white-space: normal; text-align: left; }
.sheet-modal .avail-btn { display: block; width: 100%; margin-top: .5rem; }
.sheet-modal p { color: var(--ink); }
.avail-btn.danger { background: #b91c1c; color: #fff; }
