/* ============================================================
   CSS Custom Properties (Theme Variables)
   ============================================================ */
:root {
  /* Surface colours: always carry #fff text, so they must stay dark enough
     in BOTH themes — they are deliberately not overridden below. */
  --primary: #2e7d32;
  --primary-light: #4caf50;
  --primary-dark: #1b5e20;
  --secondary: #cc4a00;
  --secondary-light: #ff8a50;
  --secondary-dark: #bf360c;

  /* Accent colours: drawn as text/borders ON the page background, so they
     must flip with the theme to keep 4.5:1. Use these — not --primary /
     --secondary — whenever the colour lands on --bg-default or --bg-paper. */
  --accent: #2e7d32;
  --accent-error: #bf360c;
  --accent-warning: #b35c00;
  --focus-ring: #1b5e20;

  --bg-default: #fff8e1;
  --bg-paper: #ffffff;
  --text-primary: #1a1a1a;
  --text-secondary: #555;
  --border-radius: 8px;
  --shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}

[data-theme="dark"] {
  --bg-default: #1a1a1a;
  --bg-paper: #2d2d2d;
  --text-primary: #f0f0f0;
  --text-secondary: #aaa;
  --accent: #6abf69;
  --accent-error: #ff8a50;
  --accent-warning: #ffb74d;
  --focus-ring: #a5d6a7;
}

/* ============================================================
   CSS Reset / Base
   ============================================================ */
*,
*::before,
*::after {
  box-sizing: border-box;
}

/* iOS Safari inflates font sizes per block when a phone is rotated to
   landscape ("text autosizing"). The inflated text changes the layout width,
   the new width changes the inflation factor, and the page oscillates through
   the whole rotation. Pinching stops it only because a manual zoom disables
   autosizing — and leaves the page stuck at the user's scale. Pinning this to
   100% keeps the declared sizes in both orientations. */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family:
    "Segoe UI",
    system-ui,
    -apple-system,
    sans-serif;
  background-color: var(--bg-default);
  color: var(--text-primary);
  line-height: 1.6;
  transition:
    background-color 0.3s,
    color 0.3s;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  margin-top: 0;
  line-height: 1.3;
}

a {
  color: var(--accent);
  text-decoration: none;
}

a:hover,
a:focus-visible {
  text-decoration: underline;
}

/* Links sitting inside running text must not be identified by colour alone
   (1.4.1). The accent reads at only 1.45:1 against body text in light mode and
   1.03:1 in dark, far below the 3:1 that would let colour carry it, so prose
   links are underlined. Buttons, chips and nav items all carry a class and are
   excluded — their shape already sets them apart from the surrounding text. */
p a:not([class]),
li a:not([class]),
figcaption a:not([class]),
.legal-section a:not([class]),
.cookie-banner-text a {
  text-decoration: underline;
}

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

ul,
ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

p {
  margin-top: 0;
}

/* ============================================================
   Accessibility helpers
   ============================================================ */

/* Visible to screen readers only. Used for skip links, icon-button labels
   and textual equivalents of colour/emoji-only information. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* A .sr-only element that reveals itself once focused — the skip link. */
.sr-only-focusable:focus,
.sr-only-focusable:focus-visible {
  position: fixed;
  top: 0.5rem;
  left: 0.5rem;
  z-index: 5000;
  width: auto;
  height: auto;
  margin: 0;
  padding: 0.75rem 1.25rem;
  overflow: visible;
  clip: auto;
  clip-path: none;
  white-space: normal;
  background-color: var(--bg-paper);
  color: var(--accent);
  font-weight: 700;
  border-radius: var(--border-radius);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
}

/* Global focus indicator. The UA default is unreliable across themes and is
   invisible on our green surfaces, so every focusable element gets an
   explicit ring; :focus-visible keeps it off for mouse users. */
:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: 2px;
}

/* Controls that sit on the green navbar / drawer header need a light ring —
   the dark-green default would disappear against the background. */
.navbar :focus-visible,
.drawer-header :focus-visible,
.stats-banner :focus-visible,
thead :focus-visible {
  outline-color: #fff;
}

/* main is focus-targeted by the skip link but must not show a ring for it. */
main:focus {
  outline: none;
}

/* Honour the OS "reduce motion" setting: no slides, lifts, scales or spins. */
@media (prefers-reduced-motion: reduce) {

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .card-hover:hover,
  .photo-gallery .gallery-item:hover img,
  .cookie-float-btn:hover {
    transform: none;
  }
}

/* ============================================================
   Container
   ============================================================ */
.container {
  max-width: 1200px;
  margin-left: auto;
  margin-right: auto;
  padding-left: 1rem;
  padding-right: 1rem;
}

/* ============================================================
   Navbar
   ============================================================ */
.navbar {
  position: sticky;
  top: 0;
  z-index: 1000;
  background-color: var(--primary);
  color: #fff;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
}

.navbar-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 1rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 56px;
}

.navbar-brand {
  font-size: 1.15rem;
  font-weight: 700;
  color: #fff;
  text-decoration: none;
  white-space: nowrap;
  flex-shrink: 0;
}

.navbar-brand:hover {
  text-decoration: none;
  opacity: 0.9;
}

/* Wraps rather than nowraps: the buttons carry white-space: nowrap and do not
   shrink, so with nowrap here they spilled straight out of the flex box and
   widened the document past the viewport (iOS then shrink-to-fits the whole
   page). Wrapping absorbs an over-long nav into a second row instead. The box
   must stay overflow: visible — .more-dropdown is absolutely positioned inside
   it and any clipping would cut the dropdown off. */
.nav-links {
  display: flex;
  align-items: center;
  gap: 0.15rem;
  flex: 1;
  flex-wrap: wrap;
  overflow: visible;
}

.nav-btn {
  background: none;
  border: none;
  /* 0.9 alpha rendered at 4.49:1 on --primary — a hair under AA. */
  color: rgba(255, 255, 255, 0.95);
  padding: 0.4rem 0.6rem;
  border-radius: var(--border-radius);
  cursor: pointer;
  font-size: 0.88rem;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.2s;
  display: inline-flex;
  align-items: center;
  /* WCAG 2.5.8 — 44px minimum pointer target */
  min-height: 44px;
}

.nav-btn:hover,
.nav-btn:focus-visible {
  background-color: rgba(255, 255, 255, 0.15);
  text-decoration: none;
  color: #fff;
}

.nav-btn.active {
  background-color: rgba(255, 255, 255, 0.25);
  color: #fff;
  font-weight: 700;
}

.theme-toggle {
  margin-left: auto;
  flex-shrink: 0;
  font-size: 1.2rem;
  padding: 0.3rem 0.5rem;
  min-width: 44px;
  justify-content: center;
}

.hamburger {
  display: none;
  background: none;
  border: none;
  color: #fff;
  font-size: 1.5rem;
  cursor: pointer;
  padding: 0.3rem 0.5rem;
  border-radius: var(--border-radius);
  flex-shrink: 0;
  min-width: 44px;
  min-height: 44px;
}

.hamburger:hover,
.hamburger:focus-visible {
  background-color: rgba(255, 255, 255, 0.15);
}

/* More dropdown */
.more-wrapper {
  position: relative;
}

.more-btn {
  font-size: 1.2rem;
  letter-spacing: 0.05em;
  min-width: 44px;
  justify-content: center;
}

.more-dropdown {
  display: none;
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  background-color: var(--bg-paper);
  border-radius: var(--border-radius);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
  min-width: 160px;
  z-index: 200;
  overflow: hidden;
  flex-direction: column;
}

.more-dropdown.open {
  display: flex;
}

.dropdown-item {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0.65rem 1rem;
  color: var(--text-primary);
  text-decoration: none;
  font-size: 0.9rem;
  transition: background-color 0.15s;
  white-space: nowrap;
}

.dropdown-item:hover,
.dropdown-item:focus-visible {
  background-color: var(--bg-default);
  text-decoration: none;
  color: var(--accent);
}

/* ============================================================
   Mobile Drawer
   ============================================================ */
.drawer-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  z-index: 1100;
}

.drawer-overlay.open {
  display: block;
}

.drawer {
  position: fixed;
  top: 0;
  left: 0;
  width: 260px;
  height: 100vh;
  /* 100vh ignores the iOS toolbars, so the drawer's foot ends up under them. */
  height: 100dvh;
  background-color: var(--bg-paper);
  z-index: 1200;
  transform: translateX(-100%);
  transition: transform 0.3s ease;
  overflow-y: auto;
  box-shadow: 4px 0 16px rgba(0, 0, 0, 0.18);
}

.drawer.open {
  transform: translateX(0);
}

.drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1rem 0.75rem;
  background-color: var(--primary);
  color: #fff;
}

.drawer-title {
  font-size: 1.1rem;
  font-weight: 700;
}

.drawer-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  background: none;
  border: none;
  color: #fff;
  font-size: 1.2rem;
  cursor: pointer;
  padding: 0.25rem 0.5rem;
  border-radius: var(--border-radius);
}

.drawer-close:hover,
.drawer-close:focus-visible {
  background-color: rgba(255, 255, 255, 0.2);
}

.drawer-list {
  padding: 0.5rem 0;
}

.drawer-list li {
  border-bottom: 1px solid rgba(0, 0, 0, 0.05);
}

.drawer-link {
  display: block;
  padding: 0.75rem 1.25rem;
  color: var(--text-primary);
  text-decoration: none;
  font-size: 0.95rem;
  transition:
    background-color 0.15s,
    color 0.15s;
}

.drawer-link:hover,
.drawer-link:focus-visible {
  background-color: var(--bg-default);
  color: var(--accent);
  text-decoration: none;
}

.drawer-link.active {
  color: var(--accent);
  font-weight: 700;
  background-color: rgba(46, 125, 50, 0.08);
}

.drawer-link-small {
  font-size: 0.82rem;
  color: var(--text-secondary);
  padding: 0.5rem 1.25rem;
}

.drawer-divider {
  height: 1px;
  background-color: rgba(0, 0, 0, 0.12);
  margin: 0.5rem 0;
  border: none;
}

/* ============================================================
   Footer
   ============================================================ */
.footer {
  background-color: var(--primary-dark);
  color: rgba(255, 255, 255, 0.9);
  padding: 2rem 0 1.25rem;
  margin-top: 3rem;
}

.footer-inner {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1.5rem;
  margin-bottom: 1rem;
}

.footer-title {
  font-size: 1.1rem;
  font-weight: 700;
  color: #fff;
  margin-bottom: 0.25rem;
}

.footer-subtitle {
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.7);
}

.footer-link {
  color: rgba(255, 255, 255, 0.8);
  text-decoration: none;
  font-size: 0.9rem;
  transition: color 0.2s;
}

.footer-link:hover,
.footer-link:focus-visible {
  color: #fff;
  text-decoration: underline;
}

.footer-divider {
  border: none;
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  margin: 1rem 0;
}

.footer-legal {
  display: flex;
  gap: 1.5rem;
  flex-wrap: wrap;
  margin-bottom: 0.75rem;
}

/* 0.55 alpha rendered at 3.63:1 on --primary-dark; 0.75 reaches 5.2:1. */
.footer-copy {
  font-size: 0.8rem;
  color: rgba(255, 255, 255, 0.75);
  margin: 0;
}

/* ============================================================
   Cards
   ============================================================ */
.card {
  background-color: var(--bg-paper);
  border-radius: var(--border-radius);
  box-shadow: var(--shadow);
  padding: 1.5rem;
  transition:
    box-shadow 0.2s,
    transform 0.2s;
  display: flex;
  flex-direction: column;
}

/* Cards in a grid row stretch to a common height, and the leftover space has
   to land somewhere. Growing the body copy puts it between the end of the text
   and the chip / info rows, which stay pinned to the bottom edge.

   The two exclusions matter:
     - .card-subtitle would otherwise grow too, so a card with a subtitle split
       the slack between the subtitle and the body — a white block directly
       under the binomial, with the description shoved to the bottom. Compare
       Milano Real (short text, big gap) against Cernícalo Primilla (long text,
       no gap) on fauna.html.
     - an empty <p> would grow into a gap with nothing in it. servicios.html
       has one, from a stray </p>. */
.card>p:not(.card-subtitle):not(:empty) {
  flex: 1;
}

.card-hover:hover,
.card-hover:focus-within {
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.16);
  transform: translateY(-3px);
}

/* A card's lead image, bled to the card's edges: the negative margin cancels
   the 1.5rem padding on .card above, and the width grows by that 1.5rem on
   each side to fill the gap. Both numbers are tied to .card's padding — change
   one and you must change all three. Only the top corners are rounded; the
   bottom of the image meets the card's body.

   Height comes from a custom property so the four sizes in use share one rule.
   The modifiers below are additive: class="card-img card-img-sm". */
.card-img {
  width: calc(100% + 3rem);
  height: var(--card-img-height, 180px);
  object-fit: cover;
  border-radius: var(--border-radius) var(--border-radius) 0 0;
  margin: -1.5rem -1.5rem 1rem;
}

.card-img-sm {
  --card-img-height: 160px;
}

.card-img-lg {
  --card-img-height: 190px;
}

.card-img-xl {
  --card-img-height: 200px;
}

.card-title {
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: 0.35rem;
}

.card-subtitle {
  font-size: 0.85rem;
  color: var(--text-secondary);
  font-style: italic;
  margin-bottom: 0.5rem;
}

/* ============================================================
   Chips / Badges
   ============================================================ */
.chip {
  display: inline-block;
  padding: 0.2rem 0.6rem;
  border-radius: 12px;
  font-size: 0.75rem;
  font-weight: 600;
  margin: 0.15rem;
  letter-spacing: 0.02em;
}

.chip-primary {
  background-color: var(--primary);
  color: #fff;
}

.chip-secondary {
  background-color: var(--secondary);
  color: #fff;
}

/* Chip backgrounds carry #fff labels at 0.75rem/600, so each needs 4.5:1.
   The originals (#388e3c 4.12:1, #f57c00 2.70:1, #0288d1 3.86:1) all failed;
   these are the same hues darkened just past the threshold. */
.chip-success {
  background-color: #2d7a31;
  color: #fff;
}

.chip-warning {
  background-color: #b35c00;
  color: #fff;
}

.chip-outlined {
  background-color: transparent;
  border: 1.5px solid var(--accent);
  color: var(--accent);
}

.chip-info {
  background-color: #0277bd;
  color: #fff;
}

/* ============================================================
   Hero Banner
   ============================================================ */
.hero {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 340px;
  /* A phone in landscape is only ~390px tall, so a fixed hero floor eats the
     whole screen. Cap it at 80% of the *dynamic* viewport height; the min()
     leaves the 340px floor untouched in portrait and on desktop. */
  min-height: min(340px, 80dvh);
  text-align: center;
  color: #fff;
}

/* The hero backdrop is a real <img> rather than a CSS background so the
   preload scanner can discover it — a background-image is only fetched once
   CSS has parsed and layout has reached the element, which pushes back LCP.
   It is taken out of flow so it behaves exactly like the old background. */
.hero > picture {
  position: absolute;
  inset: 0;
}

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

.hero-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.22);
  /*sombra portada*/
}

.hero-content {
  position: relative;
  z-index: 1;
  padding: 2rem 1rem;
  max-width: 760px;
}

.hero-content h1 {
  font-size: clamp(1.8rem, 4vw, 3rem);
  margin-bottom: 0.75rem;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}

.hero-content p {
  font-size: 1.1rem;
  opacity: 0.92;
  margin-bottom: 1.5rem;
}

.hero-buttons {
  display: flex;
  gap: 1rem;
  justify-content: center;
  flex-wrap: wrap;
}

/* ============================================================
   Buttons
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.6rem 1.4rem;
  border-radius: var(--border-radius);
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  border: 2px solid transparent;
  transition:
    background-color 0.2s,
    color 0.2s,
    border-color 0.2s,
    box-shadow 0.2s;
  text-decoration: none;
  gap: 0.4rem;
}

.btn:hover {
  text-decoration: none;
}

.btn-primary {
  background-color: var(--primary);
  color: #fff;
  border-color: var(--primary);
}

.btn-primary:hover,
.btn-primary:focus-visible {
  background-color: var(--primary-dark);
  border-color: var(--primary-dark);
  color: #fff;
}

.btn-outlined {
  background-color: transparent;
  color: var(--accent);
  border-color: var(--accent);
}

.btn-outlined:hover,
.btn-outlined:focus-visible {
  background-color: var(--primary);
  color: #fff;
  border-color: var(--primary);
}

.btn-outlined-white {
  background-color: transparent;
  color: #fff;
  border-color: #fff;
}

.btn-outlined-white:hover,
.btn-outlined-white:focus-visible {
  background-color: rgba(255, 255, 255, 0.2);
  color: #fff;
}

/* Sits on a photographic hero, so the theme ring cannot be trusted here. */
.btn-outlined-white:focus-visible {
  outline-color: #fff;
  box-shadow: 0 0 0 6px rgba(0, 0, 0, 0.55);
}

.btn-text {
  background: none;
  border-color: transparent;
  color: var(--accent);
  padding: 0.4rem 0.6rem;
  font-size: 0.9rem;
}

.btn-text:hover,
.btn-text:focus-visible {
  background-color: rgba(46, 125, 50, 0.08);
}

.btn-sm {
  padding: 0.35rem 0.9rem;
  font-size: 0.85rem;
  min-height: 44px;
}

.btn-lg {
  padding: 0.8rem 2rem;
  font-size: 1.05rem;
}

/* ============================================================
   Grid System
   ============================================================ */
.grid {
  display: grid;
  gap: 1.5rem;
}

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

.grid-3 {
  grid-template-columns: repeat(3, 1fr);
}

.grid-4 {
  grid-template-columns: repeat(4, 1fr);
}

/* ============================================================
   Stats Banner
   ============================================================ */
.stats-banner {
  background-color: var(--primary);
  color: #fff;
  padding: 3rem 0;
}

.stats-value {
  font-size: 2.2rem;
  font-weight: 800;
  color: #fff;
  margin-bottom: 0.25rem;
  line-height: 1;
}

/* 0.8 alpha rendered at 4.03:1 on --primary; 0.92 reaches 4.76:1. */
.stats-label {
  font-size: 0.9rem;
  color: rgba(255, 255, 255, 0.92);
  font-weight: 500;
}

/* ============================================================
   Table Styles
   ============================================================ */
.table-container {
  width: 100%;
  overflow-x: auto;
  border-radius: var(--border-radius);
  box-shadow: var(--shadow);
  background-color: var(--bg-paper);
  margin-bottom: 2rem;
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.92rem;
}

thead th {
  background-color: var(--primary);
  color: #fff;
  padding: 0.75rem 1rem;
  text-align: left;
  font-weight: 600;
  white-space: nowrap;
}

tbody tr:nth-child(even) {
  background-color: rgba(46, 125, 50, 0.05);
}

tbody tr:hover {
  background-color: rgba(46, 125, 50, 0.1);
}

tbody td {
  padding: 0.7rem 1rem;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
  color: var(--text-primary);
}

[data-theme="dark"] tbody td {
  border-bottom-color: rgba(255, 255, 255, 0.06);
}

[data-theme="dark"] tbody tr:nth-child(even) {
  background-color: rgba(255, 255, 255, 0.04);
}

[data-theme="dark"] tbody tr:hover {
  background-color: rgba(76, 175, 80, 0.1);
}

/* ============================================================
   Timeline
   ============================================================ */
.timeline {
  position: relative;
  padding: 1rem 0;
  margin: 2rem 0;
}

.timeline::before {
  content: "";
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: 0;
  bottom: 0;
  width: 2px;
  background-color: var(--primary-light);
}

.timeline-item {
  display: flex;
  justify-content: flex-end;
  padding-right: calc(50% + 2rem);
  margin-bottom: 2rem;
  position: relative;
}

.timeline-item:nth-child(even) {
  justify-content: flex-start;
  padding-right: 0;
  padding-left: calc(50% + 2rem);
}

.timeline-dot {
  position: absolute;
  left: 50%;
  top: 1.25rem;
  transform: translateX(-50%);
  width: 14px;
  height: 14px;
  background-color: var(--primary);
  border: 3px solid var(--bg-default);
  border-radius: 50%;
  z-index: 1;
}

.timeline-content {
  background-color: var(--bg-paper);
  border-radius: var(--border-radius);
  box-shadow: var(--shadow);
  padding: 1.25rem 1.5rem;
  max-width: 380px;
  width: 100%;
}

.timeline-year {
  display: inline-block;
  background-color: var(--primary);
  color: #fff;
  font-size: 0.8rem;
  font-weight: 700;
  padding: 0.15rem 0.6rem;
  border-radius: 12px;
  margin-bottom: 0.5rem;
}

.timeline-title {
  font-size: 1rem;
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: 0.35rem;
}

.timeline-text {
  font-size: 0.88rem;
  color: var(--text-secondary);
  margin: 0;
}

/* ============================================================
   Form Styles
   ============================================================ */
.form-group {
  margin-bottom: 1.25rem;
}

.form-group label {
  display: block;
  font-size: 0.9rem;
  font-weight: 600;
  margin-bottom: 0.4rem;
  color: var(--text-primary);
}

.form-input,
.form-textarea,
.form-select {
  width: 100%;
  padding: 0.65rem 0.9rem;
  border: 1.5px solid rgba(0, 0, 0, 0.18);
  border-radius: var(--border-radius);
  background-color: var(--bg-paper);
  color: var(--text-primary);
  font-size: 0.95rem;
  font-family: inherit;
  transition:
    border-color 0.2s,
    box-shadow 0.2s;
}

/* The former indicator was a 15%-alpha glow (~1.1:1) behind `outline: none`,
   i.e. effectively no focus indicator at all. Keep the border/glow as
   decoration and let the global :focus-visible ring do the real work. */
.form-input:focus,
.form-textarea:focus,
.form-select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(46, 125, 50, 0.15);
}

/* Fields flagged by validation. Paired with aria-invalid, never colour alone. */
.form-input[aria-invalid="true"],
.form-textarea[aria-invalid="true"],
.form-select[aria-invalid="true"] {
  border-color: var(--accent-error);
}

.form-textarea {
  resize: vertical;
  min-height: 130px;
}

[data-theme="dark"] .form-input,
[data-theme="dark"] .form-textarea,
[data-theme="dark"] .form-select {
  border-color: rgba(255, 255, 255, 0.18);
  background-color: #3a3a3a;
}

.checkbox-group {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
}

.checkbox-group input[type="checkbox"] {
  margin-top: 0.2rem;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  accent-color: var(--primary);
  cursor: pointer;
}

/* The box itself stays 24px; the label extends the pointer target past 44px
   (WCAG 2.5.8 allows the target to be the whole label). */
.checkbox-group label {
  display: block;
  align-items: center;
  min-height: 44px;
  font-size: 0.88rem;
  font-weight: 400;
  margin: 0;
  color: var(--text-secondary);
  cursor: pointer;
}

/* ============================================================
   Photo Gallery (Masonry CSS Columns)
   ============================================================ */
.photo-gallery {
  columns: 3;
  column-gap: 1rem;
}

.photo-gallery .gallery-item {
  break-inside: avoid;
  margin-bottom: 1rem;
  border-radius: var(--border-radius);
  overflow: hidden;
  box-shadow: var(--shadow);
}

.photo-gallery .gallery-item img {
  width: 100%;
  display: block;
  transition: transform 0.3s;
}

.photo-gallery .gallery-item:hover img {
  transform: scale(1.03);
}

/* ============================================================
   Cookie Banner
   ============================================================ */
.cookie-banner {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 2000;
  background-color: var(--bg-paper);
  box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.15);
  padding: 1rem;
  display: flex;
  justify-content: center;
  border-top: 3px solid var(--primary);
}

.cookie-banner-content {
  max-width: 960px;
  width: 100%;
}

.cookie-banner-text {
  font-size: 0.88rem;
  color: var(--text-secondary);
  margin-bottom: 0.75rem;
  line-height: 1.5;
}

.cookie-banner-text a {
  color: var(--accent);
}

.cookie-banner-buttons {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.cookie-btn {
  padding: 0.5rem 1.1rem;
  border-radius: var(--border-radius);
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  border: 1.5px solid transparent;
  transition:
    background-color 0.2s,
    color 0.2s;
  font-family: inherit;
  min-height: 44px;
}

.cookie-btn-accept {
  background-color: var(--primary);
  color: #fff;
  border-color: var(--primary);
}

.cookie-btn-accept:hover,
.cookie-btn-accept:focus-visible {
  background-color: var(--primary-dark);
}

.cookie-btn-reject {
  background-color: transparent;
  color: var(--text-secondary);
  border-color: rgba(0, 0, 0, 0.35);
}

[data-theme="dark"] .cookie-btn-reject {
  border-color: rgba(255, 255, 255, 0.35);
}

.cookie-btn-reject:hover,
.cookie-btn-reject:focus-visible {
  background-color: rgba(0, 0, 0, 0.05);
}

.cookie-btn-configure {
  background-color: transparent;
  color: var(--accent);
  border-color: var(--accent);
}

.cookie-btn-configure:hover,
.cookie-btn-configure:focus-visible {
  background-color: rgba(46, 125, 50, 0.08);
}

.cookie-btn-save {
  background-color: var(--secondary);
  color: #fff;
  border-color: var(--secondary);
}

.cookie-btn-save:hover,
.cookie-btn-save:focus-visible {
  background-color: var(--secondary-dark);
}

/* Escape hatch from the preferences modal — previously the only way out was a
   backdrop click, which is mouse-only. */
.cookie-btn-cancel {
  background-color: transparent;
  color: var(--text-secondary);
  border-color: rgba(0, 0, 0, 0.35);
}

[data-theme="dark"] .cookie-btn-cancel {
  border-color: rgba(255, 255, 255, 0.35);
}

.cookie-btn-cancel:hover,
.cookie-btn-cancel:focus-visible {
  background-color: rgba(0, 0, 0, 0.05);
}

/* Cookie Preferences Modal */
.cookie-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 3000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}

.cookie-modal {
  background-color: var(--bg-paper);
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.22);
  padding: 2rem;
  max-width: 520px;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
}

.cookie-modal-title {
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: 1.5rem;
}

/* The two categories are grouped in a <fieldset>; strip its default chrome. */
.cookie-categories {
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}

.cookie-category {
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
  padding: 1rem 0;
}

.cookie-category:last-of-type {
  border-bottom: none;
}

.cookie-category-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.4rem;
}

.cookie-category-name {
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--text-primary);
}

.cookie-always-on {
  font-size: 0.78rem;
  background-color: var(--primary);
  color: #fff;
  padding: 0.15rem 0.55rem;
  border-radius: 10px;
  font-weight: 600;
}

.cookie-category-desc {
  font-size: 0.83rem;
  color: var(--text-secondary);
  margin: 0;
}

.cookie-modal-buttons {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-top: 1.5rem;
}

/* Toggle Switch */
.toggle-switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: 46px;
  height: 44px;
  flex-shrink: 0;
}

/* The input is visually hidden but must stay in the layout so the focus ring
   below has a box to be drawn around. */
.toggle-switch input {
  position: absolute;
  opacity: 0;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  cursor: pointer;
}

.toggle-slider {
  position: absolute;
  cursor: pointer;
  top: 50%;
  left: 0;
  width: 46px;
  height: 26px;
  transform: translateY(-50%);
  /* #ccc sat at 1.6:1 against the modal surface — below the 3:1 that 1.4.11
     requires for a control boundary. */
  background-color: #6b6b6b;
  border-radius: 26px;
  transition: 0.3s;
}

/* The input carries no visible box of its own, so the ring is painted on the
   slider instead — otherwise this control has no focus indicator whatsoever. */
.toggle-switch input:focus-visible+.toggle-slider {
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
}

.toggle-slider::before {
  content: "";
  position: absolute;
  height: 20px;
  width: 20px;
  left: 3px;
  bottom: 3px;
  background-color: #fff;
  border-radius: 50%;
  transition: 0.3s;
}

.toggle-switch input:checked+.toggle-slider {
  background-color: var(--primary);
}

.toggle-switch input:checked+.toggle-slider::before {
  transform: translateX(20px);
}

/* Floating Cookie Button */
.cookie-float-btn {
  position: fixed;
  bottom: 1.5rem;
  right: 1.5rem;
  z-index: 1500;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background-color: var(--primary);
  color: #fff;
  border: none;
  cursor: pointer;
  font-size: 1.3rem;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.25);
  transition:
    transform 0.2s,
    box-shadow 0.2s;
}

.cookie-float-btn:hover,
.cookie-float-btn:focus-visible {
  transform: scale(1.1);
  box-shadow: 0 5px 18px rgba(0, 0, 0, 0.3);
}

/* ============================================================
   Progress Bar
   ============================================================ */
.progress-bar-container {
  width: 100%;
  background-color: rgba(0, 0, 0, 0.1);
  border-radius: 8px;
  height: 8px;
  overflow: hidden;
  margin: 0.4rem 0 0.8rem;
}

.progress-bar-fill {
  height: 100%;
  border-radius: 8px;
  transition: width 0.4s ease;
  background-color: var(--primary);
}

.progress-bar-fill.easy {
  background-color: var(--primary-light);
}

.progress-bar-fill.medium {
  background-color: #ffa726;
}

.progress-bar-fill.hard {
  background-color: var(--secondary);
}

/* ============================================================
   Layout With Sidebar
   ============================================================ */
.layout-with-sidebar {
  display: flex;
  gap: 2rem;
  align-items: flex-start;
}

.main-content {
  flex: 1;
  min-width: 0;
}

.sidebar {
  width: 300px;
  flex-shrink: 0;
}

.sidebar-sticky {
  position: sticky;
  top: 70px;
}

/* ============================================================
   Info Box / Section styles
   ============================================================ */
.section-title {
  font-size: 1.6rem;
  font-weight: 700;
  color: var(--accent);
  margin-bottom: 0.5rem;
}

.section-subtitle {
  color: var(--text-secondary);
  font-size: 1rem;
  margin-bottom: 2rem;
}

.info-card {
  background-color: var(--bg-paper);
  border-radius: var(--border-radius);
  box-shadow: var(--shadow);
  padding: 1.5rem;
}

.info-row {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  margin-bottom: 0.75rem;
  font-size: 0.92rem;
  color: var(--text-secondary);
}

.info-row .info-icon {
  flex-shrink: 0;
  font-size: 1.1rem;
}

.info-row strong {
  color: var(--text-primary);
  margin-right: 0.25rem;
}

/* ============================================================
   Alert / Notice Banner
   ============================================================ */
.notice {
  padding: 1rem 1.25rem;
  border-radius: var(--border-radius);
  font-size: 0.9rem;
  margin-bottom: 1.5rem;
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
}

.notice-info {
  background-color: #e3f2fd;
  color: #0d47a1;
  border-left: 4px solid #1976d2;
}

/* #e65100 on #fff8e1 was 3.57:1; #BF360C reaches 5.28:1 on the same tint. */
.notice-warning {
  background-color: #fff8e1;
  color: #bf360c;
  border-left: 4px solid #b35c00;
}

.notice-success {
  background-color: #e8f5e9;
  color: #1b5e20;
  border-left: 4px solid #2e7d32;
}

[data-theme="dark"] .notice-info {
  background-color: #0d2137;
  color: #90caf9;
}

[data-theme="dark"] .notice-warning {
  background-color: #2a1800;
  color: #ffcc80;
}

[data-theme="dark"] .notice-success {
  background-color: #0d2010;
  color: #a5d6a7;
}

/* ============================================================
   Legal / Policy Pages
   ============================================================ */
.legal-section {
  background-color: var(--bg-paper);
  border-radius: var(--border-radius);
  box-shadow: var(--shadow);
  padding: 2.5rem;
  margin-bottom: 2rem;
}

.legal-section h2 {
  color: var(--accent);
  font-size: 1.25rem;
  margin-bottom: 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 2px solid rgba(46, 125, 50, 0.15);
}

.legal-section h3 {
  color: var(--text-primary);
  font-size: 1.05rem;
  margin-top: 1.5rem;
  margin-bottom: 0.5rem;
}

.legal-section p,
.legal-section li {
  font-size: 0.93rem;
  color: var(--text-secondary);
  line-height: 1.7;
}

.legal-section ul {
  list-style: disc;
  padding-left: 1.5rem;
  margin-bottom: 1rem;
}

/* ============================================================
   Utility Classes
   ============================================================ */
.text-center {
  text-align: center;
}

.text-muted {
  color: var(--text-secondary);
}

.mt-2 {
  margin-top: 1rem;
}

.mt-3 {
  margin-top: 1.5rem;
}

.mt-4 {
  margin-top: 2rem;
}

.mb-0 {
  margin-bottom: 0;
}

.mb-2 {
  margin-bottom: 1rem;
}

.mb-3 {
  margin-bottom: 1.5rem;
}

.mb-4 {
  margin-bottom: 2rem;
}

.w-full {
  width: 100%;
}

.flex {
  display: flex;
}

.flex-wrap {
  flex-wrap: wrap;
}

.rounded {
  border-radius: var(--border-radius);
}

.shadow {
  box-shadow: var(--shadow);
}

/* ============================================================
   Responsive Breakpoints
   ============================================================ */

/* Tablet: < 1024px */
@media (max-width: 1024px) {
  .grid-4 {
    grid-template-columns: repeat(2, 1fr);
  }

  .sidebar {
    width: 250px;
  }
}

/* Nav breakpoint, deliberately wider than the 768px mobile one below. The
   full-word nav row (brand + 7 links + ⋮ + theme toggle) needs about 1020px,
   and a phone in landscape reports 844–932 CSS px — wide enough to leave
   mobile mode and get a desktop nav that does not fit. Keeping the drawer up
   to 900px is what stops the page overflowing sideways there. Only the nav
   moves at this width; the grids and the rest still switch at 768px. */
@media (max-width: 900px) {
  .nav-links {
    display: none;
  }

  .hamburger {
    display: flex;
    align-items: center;
    justify-content: center;
  }
}

/* Mobile: < 768px */
@media (max-width: 768px) {
  .grid-2,
  .grid-3,
  .grid-4 {
    grid-template-columns: 1fr;
  }

  .layout-with-sidebar {
    flex-direction: column;
  }

  .sidebar {
    width: 100%;
  }

  .ad-sidebar {
    width: 100%;
    min-height: 90px;
  }

  .timeline::before {
    left: 16px;
  }

  .timeline-item,
  .timeline-item:nth-child(even) {
    justify-content: flex-start;
    padding-left: 3rem;
    padding-right: 0;
  }

  .timeline-dot {
    left: 16px;
  }

  .timeline-content {
    max-width: 100%;
  }

  .hero-content h1 {
    font-size: 1.7rem;
  }

  .photo-gallery {
    columns: 2;
  }

  .footer-inner {
    flex-direction: column;
  }

  .footer-legal {
    flex-direction: column;
    gap: 0.6rem;
  }

  .cookie-banner-buttons {
    gap: 0.5rem;
  }

  .cookie-btn {
    font-size: 0.82rem;
    padding: 0.45rem 0.85rem;
  }

  .stats-value {
    font-size: 1.75rem;
  }

  .legal-section {
    padding: 1.5rem;
  }

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

/* Grids of picture cards, on a phone held sideways.
   A phone in landscape is 568-932px wide, so it straddles the 768px mobile
   breakpoint: the wider ones kept three columns and squeezed each card to
   ~280px, while the narrower ones dropped all the way to one. Two columns
   suit the shape in both cases.

   Opt-in via .photo-card-grid rather than applied to every .grid-3, because
   it is the image that makes a narrow column read badly. Grids of text- or
   emoji-only cards keep the plain 3/1 behaviour — `servicios.html`'s
   "Servicios Locales" block is one of those, and is deliberately not tagged.

   `max-height` is what separates a phone from a tablet — width alone cannot,
   since a 932px phone in landscape and an 820px tablet in portrait overlap.
   Phones in landscape are ~375-450px tall; the smallest tablet is 744px, so
   600px sits in the gap.

   Must stay after the 768px block above: `.grid-3` there is one class too, so
   source order is what makes this win. */
@media (max-width: 1024px) and (orientation: landscape) and (max-height: 600px) {
  .photo-card-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Small mobile: < 480px */
@media (max-width: 480px) {
  .photo-gallery {
    columns: 1;
  }

  .grid.grid-4 {
    grid-template-columns: 1fr;
  }

  .hero-buttons {
    flex-direction: column;
    align-items: center;
  }

  .stats-banner .grid-4 {
    grid-template-columns: repeat(2, 1fr);
    gap: 1.5rem;
  }
}

/* ============================================================
   Autocomplete Dropdown
   ============================================================ */
.autocomplete-list {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 500;
  background-color: var(--bg-paper);
  border: 1.5px solid rgba(0, 0, 0, 0.18);
  border-top: none;
  border-radius: 0 0 var(--border-radius) var(--border-radius);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
  max-height: 200px;
  overflow-y: auto;
  list-style: none;
  margin: 0;
  padding: 0;
}

.autocomplete-list li {
  padding: 0.5rem 0.75rem;
  font-size: 0.9rem;
  cursor: pointer;
  color: var(--text-primary);
  transition: background-color 0.12s;
}

/* The active option is what aria-activedescendant points at, so it needs to be
   unmistakable — a 10%-alpha tint alone read at ~1.1:1. */
.autocomplete-list li:hover {
  background-color: rgba(46, 125, 50, 0.1);
  color: var(--accent);
}

.autocomplete-list li.active {
  background-color: var(--primary);
  color: #fff;
  font-weight: 600;
}

[data-theme="dark"] .autocomplete-list {
  border-color: rgba(255, 255, 255, 0.18);
}

/* ============================================================
   Table Toolbar / Search
   ============================================================ */
.table-toolbar {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 1rem;
}

.search-field {
  width: 100%;
  max-width: 26rem;
}

.search-label {
  display: block;
  margin-bottom: 0.35rem;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--text-primary);
}

/* Positioning context for the clear button and the suggestions dropdown */
.search-input-wrap {
  position: relative;
}

/* Room for the clear button on the right (44px target + gutter) */
.search-input {
  padding-right: 3.2rem;
}

.search-clear {
  position: absolute;
  top: 50%;
  right: 0.15rem;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: none;
  color: var(--text-secondary);
  font-size: 0.85rem;
  line-height: 1;
  cursor: pointer;
  transition:
    background-color 0.15s,
    color 0.15s;
}

.search-clear:hover,
.search-clear:focus-visible {
  background-color: rgba(46, 125, 50, 0.12);
  color: var(--accent);
}

.search-clear[hidden] {
  display: none;
}

/* Reserve the line height so results appearing do not shift the table */
.search-status {
  display: block;
  min-height: 1.2em;
  margin-top: 0.35rem;
  font-size: 0.82rem;
  color: var(--text-secondary);
}

@media (max-width: 600px) {
  .search-field {
    max-width: none;
  }
}

/* ============================================================
   Collapsible Toggle
   ============================================================ */
.collapsible-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: inherit;
  font-family: inherit;
  text-align: left;
}

.collapsible-toggle:hover,
.collapsible-toggle:focus-visible {
  opacity: 0.85;
}

.collapsible-icon {
  font-size: 1.3rem;
  color: var(--accent);
  transition: transform 0.25s ease;
  flex-shrink: 0;
  line-height: 1;
}

.collapsible-icon.open {
  transform: rotate(90deg);
}

/* ============================================================
   Pagination
   ============================================================ */
.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  flex-wrap: wrap;
  margin: 1.5rem 0;
}

.pagination-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  height: 44px;
  padding: 0 0.55rem;
  border: 1.5px solid rgba(0, 0, 0, 0.15);
  border-radius: var(--border-radius);
  background-color: var(--bg-paper);
  color: var(--text-primary);
  font-size: 0.88rem;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition:
    background-color 0.15s,
    border-color 0.15s,
    color 0.15s;
  text-decoration: none;
}

.pagination-btn:hover,
.pagination-btn:focus-visible {
  background-color: rgba(46, 125, 50, 0.08);
  border-color: var(--accent);
  color: var(--accent);
}

.pagination-btn.active {
  background-color: var(--primary);
  border-color: var(--primary);
  color: #fff;
  cursor: default;
}

.pagination-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

.pagination-info {
  font-size: 0.82rem;
  color: var(--text-secondary);
  margin-left: 0.75rem;
}

[data-theme="dark"] .pagination-btn {
  border-color: rgba(255, 255, 255, 0.15);
}

nav-bar,
foo-bar {
  display: contents;
}

/* ============================================================
   Auth Modal & Admin UI
   ============================================================ */
.auth-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 4000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}

/* Thumbnail zoom trigger. A real button so the lightbox can be opened from the
   keyboard; styled to look exactly like the bare <img> it replaced. */
.thumb-zoom {
  display: inline-flex;
  padding: 0;
  border: none;
  background: none;
  border-radius: 6px;
  cursor: pointer;
  /* 48px image inside a 44px minimum — already satisfied by the thumbnail. */
}

/* ── Image lightbox ── */
.lightbox-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  background: rgba(0, 0, 0, 0.75);
}

.lightbox-image {
  max-width: 90vw;
  max-height: 90vh;
  object-fit: contain;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
}

.lightbox-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  border: 2px solid rgba(255, 255, 255, 0.7);
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  font-size: 1.2rem;
  cursor: pointer;
}

.lightbox-close:hover,
.lightbox-close:focus-visible {
  background: rgba(0, 0, 0, 0.85);
  border-color: #fff;
}

/* The overlay is dark in both themes, so the theme ring would not read here. */
.lightbox-overlay :focus-visible {
  outline-color: #fff;
}

.auth-modal {
  background-color: var(--bg-paper);
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.22);
  padding: 2rem;
  max-width: 420px;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
}

/* Pending rows */
.pending-row {
  background-color: rgba(230, 81, 0, 0.08) !important;
}

.pending-row:hover {
  background-color: rgba(230, 81, 0, 0.14) !important;
}

[data-theme="dark"] .pending-row {
  background-color: rgba(255, 138, 80, 0.1) !important;
}

[data-theme="dark"] .pending-row:hover {
  background-color: rgba(255, 138, 80, 0.18) !important;
}

.admin-actions {
  display: flex;
  gap: 0.35rem;
  align-items: center;
}

.admin-actions .btn {
  text-decoration: none;
  font-style: normal;
}

/* Detail modal grid */
.detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem 1.5rem;
}

.detail-field {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.detail-label {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Horarios save bar */
.horarios-save-bar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 1rem;
  padding: 1rem 0;
}

/* Small form inputs for inline editing */
.form-input-sm {
  padding: 0.35rem 0.5rem;
  font-size: 0.85rem;
  border-radius: 6px;
}

/* Admin-only elements hidden by default */
.admin-only {
  display: none;
}

/* Permission-gated elements. Hidden by default so they never flash before
   auth.module.js resolves the session and its permissions, and so they stay
   hidden if it never resolves at all (blocked CDN, offline).
   auth.module.js adds .permission-granted to reveal them; the element then
   falls back to its natural display, which differs per call site (flex item
   in the dropdown, list-item in the drawer) — hence a class rather than an
   inline display value. */
[data-requires-permission]:not(.permission-granted) {
  display: none;
}

/* ─── Admin backup dashboard ──────────────────────────────────────── */

.admin-page {
  padding: 2rem 1rem 3rem;
}

.admin-panel {
  background: var(--bg-paper);
  border-radius: var(--border-radius);
  box-shadow: var(--shadow);
  padding: 1.25rem 1.5rem;
  margin-bottom: 1.5rem;
}

.admin-panel h2 {
  margin-top: 0;
}

.admin-note {
  color: var(--text-secondary);
  font-size: 0.925rem;
  line-height: 1.5;
}

.admin-note-warn {
  border-left: 3px solid var(--accent-error);
  padding-left: 0.75rem;
}

.admin-hint {
  color: var(--text-secondary);
  font-size: 0.875rem;
  margin-top: 0.75rem;
}

.admin-error {
  color: var(--accent-error);
}

.admin-loading {
  color: var(--text-secondary);
}

.admin-meta {
  color: var(--text-secondary);
  font-size: 0.85rem;
}

.admin-summary p {
  margin: 0.25rem 0;
}

.admin-file-list {
  list-style: none;
  padding: 0;
  margin: 0.5rem 0 1rem;
  max-height: 22rem;
  overflow-y: auto;
}

.admin-file-list li {
  padding: 0.4rem 0;
  border-bottom: 1px solid rgba(128, 128, 128, 0.2);
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: baseline;
}

.admin-file-list li:last-child {
  border-bottom: none;
}

.admin-denied {
  background: var(--bg-paper);
  border-radius: var(--border-radius);
  box-shadow: var(--shadow);
  padding: 1.5rem;
}
