/* ============================================================
   Downloads page and its request form (pages/downloads.py).
   Neither had a stylesheet: the form relied on inline styles and rendered as
   browser defaults, and the cards used the old 'three columns' grid, which left
   the fifth card stranded alone on a second row.
   ============================================================ */

/* ---- Downloads page ---- */
.dl-section {
  max-width: 1400px;
  margin: 0 auto;
  padding: 28px 40px 48px;
}
.dl-head {
  margin-bottom: 22px;
}
.dl-title {
  color: #1b3b5a;
  font-size: 22px;
  font-weight: 700;
  margin: 0 0 8px;
}
.dl-subtitle {
  color: #6f8079;
  font-size: 14px;
  line-height: 1.6;
  margin: 0;
  max-width: 720px;
}

/* auto-fit means five cards spread evenly on a wide screen and reflow cleanly on
   a narrow one, instead of a fixed 4 + 1 orphan. */
.dl-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 20px;
  align-items: stretch;
}
.dl-card {
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  background: #ffffff;
  border: 1px solid #e6ece9;
  border-top: 4px solid #0bb89c;
  border-radius: 12px;
  padding: 20px 22px 18px;
  box-shadow: 0 2px 10px rgba(16, 40, 34, 0.05);
  transition: transform .18s ease, box-shadow .18s ease;
}
.dl-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 30px rgba(16, 40, 34, 0.12);
}
.dl-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}
.dl-card-title {
  color: #1b3b5a;
  font-size: 17px;
  font-weight: 700;
  margin: 0;
}
.dl-card-format {
  flex: none;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .8px;
  color: #0b7d6a;
  background: #eafaf5;
  border-radius: 999px;
  padding: 3px 9px;
}
.dl-card-desc {
  color: #55636b;
  font-size: 13.5px;
  line-height: 1.55;
  margin: 0 0 18px;
}

.download-button {
  margin-top: auto;          /* buttons line up across cards of unequal text length */
  width: 100%;
  height: 40px;
  border: 1px solid #0bb89c;
  border-radius: 8px;
  background: #0bb89c;
  color: #ffffff;
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: .3px;
  cursor: pointer;
  transition: background .15s ease, box-shadow .15s ease;
}
.download-button:hover:not(:disabled) {
  background: #0aa78d;
  box-shadow: 0 6px 16px rgba(11, 184, 156, 0.28);
}
.download-button:disabled {
  background: #f2f5f4;
  border-color: #e2e8e5;
  color: #a9b5b0;
  cursor: not-allowed;
}

/* ---- "Preparing your file" state -------------------------------------------
   Shown in place of the button while the server builds the file.

   The bar is INDETERMINATE on purpose. These are 30-50 MB downloads: the server
   spends a couple of seconds assembling the CSV and then hands it to the browser,
   and it cannot observe that transfer. Any percentage would be invented, and would
   sit at "100%" while the user was still waiting. The bar says "working"; the file
   size, shown alongside, says roughly how long "working" means.

   The runtime ships dash_core_components 2.10.2, which cannot take a custom
   spinner, so the state is drawn here instead: hide its default circle and render
   the bar and label on the wrapper while the spinner element is in the DOM. */
.dl-action {
  margin-top: auto;   /* buttons line up across cards of unequal text length */
}

/* Only take over the spinner where :has() can tell us the component is loading.
   Where it is not supported, the default green circle is left in place, so the
   user always gets *some* feedback rather than a dead button. */
@supports selector(:has(*)) {
  .dl-action .dl-spinner {
    display: none !important;
  }

  /* The indeterminate bar: a highlight sweeping across a track. Animating
     background-position (rather than a child element) keeps this to a single
     pseudo-element, which is all a CSS-only spinner replacement can use. */
  .dl-action:has(.dl-spinner)::before {
    content: "";
    display: block;
    height: 6px;
    border-radius: 999px;
    background: linear-gradient(90deg,
      #eaf1ee 0%, #eaf1ee 32%, #0bb89c 50%, #eaf1ee 68%, #eaf1ee 100%);
    background-size: 250% 100%;
    animation: dl-bar-slide 1.2s linear infinite;
  }

  .dl-action:has(.dl-spinner)::after {
    content: "Preparing your file (" attr(data-size) ")";
    display: block;
    margin-top: 9px;
    text-align: center;
    color: #6f8079;
    font-size: 12.5px;
    font-weight: 600;
  }
}

@keyframes dl-bar-slide {
  0%   { background-position: 150% 0; }
  100% { background-position: -50% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .dl-action:has(.dl-spinner)::before {
    animation: none;
    background: #0bb89c;
    opacity: .5;
  }
}

.modal-overlay {
  display: flex;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1000;
  justify-content: center;
  align-items: center;
  padding: 20px;
  box-sizing: border-box;
  /* A dimmed backdrop makes it obvious the form must be completed first, and
     stops the page behind it competing for attention. */
  background: rgba(16, 40, 34, 0.45);
  backdrop-filter: blur(2px);
}

.modal-content {
  width: 100%;
  max-width: 540px;
  max-height: 86vh;
  overflow-y: auto;
  box-sizing: border-box;
  background: #ffffff;
  border-radius: 16px;
  padding: 28px 30px 24px;
  box-shadow: 0 24px 60px rgba(10, 30, 25, 0.28);
}

/* ---- Header ---- */
.form-head {
  border-bottom: 1px solid #eef2f0;
  padding-bottom: 16px;
  margin-bottom: 18px;
}
.form-title {
  color: #1b3b5a;
  font-size: 21px;
  font-weight: 700;
  margin: 0 0 8px;
}
.form-subtitle {
  color: #6f8079;
  font-size: 13.5px;
  line-height: 1.6;
  margin: 0;
}

/* ---- Fields ---- */
.form-field {
  margin-bottom: 16px;
}
/* First / last name sit side by side: they are short and belong together. */
.form-row {
  display: flex;
  gap: 14px;
}
.form-row .form-field {
  flex: 1 1 0;
  min-width: 0;
}
.form-label {
  display: block;
  color: #44515a;
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 6px;
}
.form-required {
  color: #d9534f;
  font-weight: 700;
}
.form-hint {
  display: block;
  color: #93a29c;
  font-size: 12px;
  margin: -2px 0 6px;
}

.input-box {
  width: 100%;
  box-sizing: border-box;
  height: 40px;
  padding: 0 12px;
  border: 1px solid #dfe6e3;
  border-radius: 8px;
  background: #fbfdfc;
  color: #2c3a42;
  font-size: 14px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.input-box::placeholder {
  color: #b3bfba;
}
.input-box:focus {
  outline: none;
  border-color: #0bb89c;
  background: #ffffff;
  box-shadow: 0 0 0 3px rgba(11, 184, 156, 0.14);
}

/* dcc.Dropdown renders its own markup, so its inner control is restyled to match
   the text inputs exactly. Without this the dropdowns look like a different form. */
.dropdown-box .Select-control {
  height: 40px;
  border: 1px solid #dfe6e3;
  border-radius: 8px;
  background: #fbfdfc;
}
.dropdown-box .Select-placeholder,
.dropdown-box .Select--single > .Select-control .Select-value {
  line-height: 38px;
  padding-left: 12px;
  font-size: 14px;
}
.dropdown-box .Select-placeholder {
  color: #b3bfba;
}
.dropdown-box .Select-input {
  height: 38px;
  padding-left: 12px;
}
.dropdown-box .Select-input > input {
  padding: 10px 0;
  font-size: 14px;
}
.dropdown-box.is-focused:not(.is-open) > .Select-control {
  border-color: #0bb89c;
  box-shadow: 0 0 0 3px rgba(11, 184, 156, 0.14);
}
.dropdown-box .Select-menu-outer {
  border-radius: 8px;
  border-color: #dfe6e3;
  box-shadow: 0 10px 26px rgba(16, 40, 34, 0.12);
  z-index: 20;
}
.dropdown-box .VirtualizedSelectFocusedOption {
  background: #eafaf5;
  color: #0b7d6a;
}

.form-error {
  color: #d9534f;
  font-size: 12px;
  line-height: 1.4;
  margin-top: 5px;
  min-height: 0;
}

/* ---- "You're downloading …" banner ---------------------------------------
   Names the file the visitor clicked, so the form reads as part of getting that
   dataset rather than an unrelated gate. Filled in when the form opens. */
.form-what-inner {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  background: #eafaf5;
  border: 1px solid #cdeee4;
  border-radius: 10px;
  padding: 9px 13px;
  margin-bottom: 14px;
}
.form-what-label {
  color: #0b7d6a;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
}
.form-what-name {
  color: #1b3b5a;
  font-size: 15px;
  font-weight: 700;
}
.form-what-meta {
  margin-left: auto;
  color: #0b7d6a;
  background: #ffffff;
  border: 1px solid #cdeee4;
  border-radius: 999px;
  padding: 2px 9px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .5px;
}

/* ---- Consent + trust ---- */
.form-consent label {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  color: #55636b;
  font-size: 13px;
  line-height: 1.45;
  cursor: pointer;
  margin: 0;
}
.form-consent input[type="checkbox"] {
  margin: 2px 0 0;
  width: 16px;
  height: 16px;
  accent-color: #0bb89c;
  flex: none;
  cursor: pointer;
}
.form-trust {
  display: flex;
  align-items: center;
  gap: 7px;
  color: #8a978f;
  font-size: 12px;
  margin: 10px 0 0;
}
.form-trust-ico {
  font-size: 12.5px;
}

/* ---- Actions ---- */
.form-actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 10px;
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid #eef2f0;
}
.submit-button {
  height: 42px;
  padding: 0 22px;
  border: 1px solid #0bb89c;
  border-radius: 8px;
  background: #0bb89c;
  color: #ffffff;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.2px;
  cursor: pointer;
  transition: background .15s ease, box-shadow .15s ease, transform .15s ease;
}
.submit-button:hover {
  background: #0aa78d;
  box-shadow: 0 6px 16px rgba(11, 184, 156, 0.3);
  transform: translateY(-1px);
}
.cancel-button {
  height: 42px;
  padding: 0 18px;
  border: 1px solid #dfe6e3;
  border-radius: 8px;
  background: #ffffff;
  color: #6f8079;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease;
}
.cancel-button:hover {
  border-color: #c7d2cd;
  color: #44515a;
}
.form-actions a {
  text-decoration: none;
}

@media (max-width: 560px) {
  .modal-content { padding: 22px 18px 18px; }
  /* Stacked on a phone: two side-by-side name boxes get too cramped to type in. */
  .form-row { flex-direction: column; gap: 0; }
  .form-actions { flex-direction: column-reverse; align-items: stretch; }
  .form-actions .submit-button,
  .form-actions .cancel-button { width: 100%; }
}

/* Codes page: the same action button rendered as a link to the repository.
   An <a> needs explicit display/centring to match the <button> version. */
a.download-button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  box-sizing: border-box;
  text-decoration: none;
}
a.download-button:hover {
  color: #ffffff;   /* the global link colour would otherwise win on hover */
}
/* Marks the link as leaving the site for GitHub. */
.dl-card-arrow {
  font-size: 12px;
  line-height: 1;
}

/* The Codes page has three cards where Downloads has five. Capping the column
   width keeps the cards the same size across the two tabs, instead of three
   stretched panels that read as a different page. */
.codes-grid {
  grid-template-columns: repeat(auto-fit, minmax(230px, 320px));
  justify-content: start;
}
