:root {
  --ink: #1c2733;
  --muted: #5b6b7a;
  --paper: #f6f8fa;
  --card: #ffffff;
  --accent: #2563a8;
  --accent-2: #7fb3e0;
  --good: #2e7d52;
  --bad: #b3542e;
  --line: #dde5ec;
  /* The journey. Warm on purpose: every other colour on the map is a score
     band, so a route must not read as a rating. */
  --route: #c2410c;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  background: var(--paper);
  color: var(--ink);
  line-height: 1.55;
}

header {
  background: linear-gradient(160deg, #1d3a5f 0%, #2b5d8a 55%, #4a86b4 100%);
  color: #fff;
  padding: 2.5rem 1.25rem 1.8rem;
  text-align: center;
}
header h1 { margin: 0 0 .4rem; font-size: 2.4rem; letter-spacing: -.02em; }
.tagline { margin: 0 auto; max-width: 38rem; opacity: .92; }
/* The ENSO advisory is context for an ANSWER, not for the landing page, where
   it was two lines of state nobody had asked for yet and it pushed the first
   question down. It appears with the results instead, on the compact
   masthead — see below. */
.enso { display: none; margin: .8rem 0 0; font-size: .85rem; opacity: .75; }

/* On the results view the masthead shrinks out of the way — the answer is
   the point, not the pitch. */
header.compact { padding: 1.4rem 1.25rem 1.1rem; }
header.compact h1 { font-size: 1.35rem; }
header.compact .tagline { display: none; }
header.compact .enso { display: block; margin-top: .3rem; font-size: .8rem; }
/* The card tucks under the gradient on the landing page, where there is
   nothing beneath the tagline to hide. On the results view the advisory sits
   there, so the overlap has to give way or it clips the line. */
header.compact + main { margin-top: -.5rem; }

main { max-width: 46rem; margin: -1.6rem auto 2rem; padding: 0 1rem; }

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 1.4rem 1.5rem;
  margin-bottom: 1.2rem;
  box-shadow: 0 2px 10px rgba(29, 58, 95, .06);
}
.card h2 { font-size: 1.02rem; margin: 1.1rem 0 .55rem; }
.card h2:first-child { margin-top: 0; }

.checks { display: flex; flex-wrap: wrap; gap: .45rem .5rem; }
.checks label {
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: .32rem .8rem;
  cursor: pointer;
  user-select: none;
  font-size: .92rem;
  background: var(--paper);
  transition: all .12s ease;
}
.checks label:has(:checked) {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.checks input { display: none; }

.constraints { display: flex; flex-wrap: wrap; gap: .8rem 1.6rem; align-items: center; }
.constraints label { font-size: .92rem; color: var(--muted); }
.constraints select {
  margin-left: .4rem;
  padding: .3rem .5rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: .9rem;
  background: #fff;
  color: var(--ink);
}

.modes { display: flex; gap: .45rem; }
.modes label {
  flex: 1;
  text-align: center;
  border: 1px solid var(--line);
  border-radius: 9px;
  padding: .45rem .7rem;
  font-size: .92rem;
  background: var(--paper);
  color: var(--muted);
  cursor: pointer;
  user-select: none;
}
.modes input { display: none; }
.modes label:has(:checked) {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.modes .mode-avoid {
  background: #f6ece4;      /* light brown: visible before it is chosen */
  border-color: #e3cdba;
  color: #8a5433;
}
.modes label:has([value="avoid"]:checked) {
  background: var(--bad);
  border-color: var(--bad);
  color: #fff;
}

#go {
  margin-top: 1.3rem;
  width: 100%;
  padding: .8rem;
  font-size: 1.05rem;
  font-weight: 600;
  color: #fff;
  background: var(--accent);
  border: 0;
  border-radius: 10px;
  cursor: pointer;
}
#go:hover { background: #1d5490; }

/* results view */
.profile { padding: 1rem 1.5rem 1.1rem; }
.back {
  background: none;
  border: 0;
  color: var(--muted);
  font-size: .85rem;
  cursor: pointer;
  padding: 0 0 .6rem;
}
.back:hover { color: var(--accent); }

#results-view > h2 { margin: 1.6rem 0 .2rem; font-size: 1.25rem; }
.confidence-note { color: var(--muted); font-size: .85rem; margin: 0 0 1rem; }

.resort {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: .9rem 1.1rem;
  margin-bottom: .7rem;
}
.resort-head { display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap; cursor: pointer; }
.rank { color: var(--muted); font-size: .9rem; width: 1.4rem; }
.resort-name { font-weight: 650; font-size: 1.06rem; }
.resort-state { color: var(--muted); font-size: .85rem; }
.badges { margin-left: auto; display: flex; gap: .35rem; align-items: center; }
.badge {
  font-size: .7rem;
  padding: .12rem .5rem;
  border-radius: 999px;
  background: var(--paper);
  border: 1px solid var(--line);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .03em;
}
.badge.month { background: #eaf2fa; border-color: #cadff2; color: var(--accent); }
/* The pass belongs with the resort's identity, beside its name, not with the
   control on the far right. */
.badge.pass { margin-left: .1rem; }
.expander {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  font-size: .78rem;
  font-weight: 600;
  padding: .2rem .5rem .2rem .6rem;
  border-radius: 999px;
  background: #eaf2fa;
  border: 1px solid #b9d5ef;
  color: var(--accent);
}
.expander.climo { background: #f6f1e4; border-color: #e2d3ab; color: #8a6d1e; }
.expander .chev {
  font-size: 1.05rem;
  line-height: 1;
  transform: rotate(90deg);
  transition: transform .15s ease;
}
.resort.open .expander .chev { transform: rotate(-90deg); }
.resort-head:hover .expander { background: var(--accent); border-color: var(--accent); color: #fff; }
.resort-head:hover .expander.climo { background: #8a6d1e; border-color: #8a6d1e; color: #fff; }
.resort-head:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 6px; }
.badge.climo { background: #f6f1e4; border-color: #e8dcbf; color: #8a6d1e; }

.scorebar-wrap { flex-basis: 100%; margin-top: .5rem; }

/* Segmented rating bar: every band shown, the live band inked, the rest
   washed out, and a marker at the value. */
.segbar { position: relative; padding: 9px 0 3px; }
.segs { display: flex; height: 10px; border-radius: 4px; overflow: hidden; }
.segs .seg { height: 100%; opacity: .2; }
.segs .seg.on { opacity: 1; }
/* The marker is the whole point of the bar — it says where in the band you
   actually sit — so it is drawn large enough to find at a glance, and haloed
   so it stays legible over a dark inked band. */
.segbar .mark {
  position: absolute;
  top: 0;
  width: 0; height: 0;
  margin-left: -6px;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 9px solid var(--ink);
  filter: drop-shadow(0 0 1.5px #fff);
}

.detail { display: none; margin-top: .8rem; font-size: .88rem; border-top: 1px solid var(--line); padding-top: .8rem; }
.resort.open .detail { display: block; }
.detail table { border-collapse: collapse; width: 100%; }
.detail td { padding: .18rem .4rem .18rem 0; vertical-align: middle; }
.detail .compname { width: 7.5rem; color: var(--muted); }
.scoretable td { padding: .3rem .4rem .3rem 0; }
.scoretable .fitrow td { border-bottom: 1px solid var(--line); padding-bottom: .5rem; }
.scoretable .fitrow + tr td { padding-top: .5rem; }
/* The rating WORD carries the meaning; the chip is redundant colour, never the
   only signal — and the text stays in ink rather than the series colour. */
.detail .rating {
  width: 9rem;
  white-space: nowrap;
  color: var(--ink);
  font-size: .85rem;
  padding-left: .5rem;
}
.detail .chip {
  display: inline-block;
  width: .55rem;
  height: .55rem;
  border-radius: 2px;
  margin-right: .35rem;
}
.detail .facts { margin: .3rem 0 0; color: var(--muted); }
.detail a { color: var(--accent); }
.detail h4 {
  margin: 1rem 0 .35rem;
  font-size: .78rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--muted);
}
.detail h4:first-child { margin-top: 0; }
/* forecast-vs-normal small multiples */
.panels {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
  gap: .5rem .9rem;
}
.panel { margin: 0; }
.panel figcaption[title] { cursor: help; }
.panel figcaption {
  font-size: .78rem;
  color: var(--ink);
  margin-bottom: .1rem;
}
.panel .unit { color: var(--muted); font-weight: 400; font-size: .72rem; }
.p-axis { stroke: #c3c2b7; stroke-width: 1; }
.p-tick { font-size: 7.5px; fill: #898781; }
.p-norm { fill: none; stroke: #898781; stroke-width: 1.6; stroke-dasharray: 3 2.5; }
.p-fc { fill: none; stroke: var(--accent); stroke-width: 2; }
.p-fc-dot { fill: var(--accent); }
.p-sel { fill: var(--accent); stroke: #fff; stroke-width: 2; }
.legend { display: flex; gap: 1rem; font-size: .76rem; color: var(--muted); margin: .1rem 0 .45rem; }
.legend i { display: inline-block; width: 14px; height: 0; margin-right: .3rem; vertical-align: middle; }
.legend .k-fc { border-top: 2px solid var(--accent); }
.legend .k-norm { border-top: 2px dashed #898781; }

@media (max-width: 520px) {
  .panels { grid-template-columns: 1fr; }
}

.terciles {
  display: flex;
  height: 20px;
  border-radius: 4px;
  overflow: hidden;
  margin: .35rem 0 .2rem;
}
.terciles span {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.terciles b {
  font-size: .7rem;
  font-weight: 600;
  white-space: nowrap;
  color: #fff;
}
.terciles .t-near b { color: var(--ink); }
.t-below { background: #c98a5a; }
.t-near { background: #d8dde2; }
.t-above { background: #6a9fd8; }

.method p { font-size: .92rem; color: var(--ink); }
/* Keep the underline: a link inside a heading is not expected, so colour
   alone would not read as one. Accent colour matches the footer links. */
.method h2 a { color: var(--accent); text-underline-offset: 2px; }
.fine { font-size: .78rem; color: var(--muted); }

footer {
  text-align: center;
  color: var(--muted);
  font-size: .8rem;
  padding: 1rem 1rem 2.4rem;
  max-width: 44rem;
  margin: 0 auto;
}

/* On a phone the masthead was taking 36% of the screen, which pushed "Find my
   mountains" below the fold — the pitch was outranking the thing you came to
   press. Trim the header and tighten the card so the whole questionnaire,
   button included, fits a 393x659 viewport without scrolling. */
@media (max-width: 480px) {
  header { padding: 1.3rem 1rem .9rem; }
  header h1 { font-size: 1.55rem; }
  .tagline { font-size: .9rem; }
  header.compact .enso { margin-top: .4rem; font-size: .76rem; }
  /* The card tucks under the gradient, but the phone header has far less
     bottom padding than the desktop one, so the same overlap ate the
     tagline's second line. */
  main { margin-top: -.7rem; padding: 0 .75rem; }
  .card { padding: 1rem .95rem; }
  .card h2 { font-size: .98rem; margin: .8rem 0 .4rem; }
  .constraints { gap: .55rem 1.2rem; }
  .badges { margin-left: 0; }
  /* Adding the Map pill cost the head row ~55 px, enough to wrap the pills
     under longer names on a phone. Tighten both rather than drop a label. */
  .mapbtn, .expander { font-size: .72rem; padding: .18rem .45rem; }
  .badges { gap: .28rem; }
}

/* Short phones (the 4.7" SE leaves about 553 px of viewport) need another
   ~20 px to clear the button. Type and padding only — nothing is hidden. */
@media (max-width: 480px) and (max-height: 620px) {
  header { padding: 1rem 1rem .75rem; }
  header h1 { font-size: 1.4rem; }
  .tagline { font-size: .85rem; }
  .card h2 { margin: .65rem 0 .35rem; }
  .checks label { padding: .28rem .7rem; }
  .checks { gap: .35rem .45rem; }
  .constraints { gap: .45rem 1rem; }
  #go { margin-top: .9rem; padding: .7rem; }
}

/* ---- map ---- */
#map-toggle {
  margin-top: .7rem;
  width: 100%;
  padding: .6rem;
  font-size: .95rem;
  font-weight: 600;
  color: var(--accent);
  background: var(--paper);
  border: 1px solid #b9d5ef;
  border-radius: 10px;
  cursor: pointer;
}
#map-toggle:hover { background: #eaf2fa; }

#map-panel { margin-bottom: 1.2rem; }
#map {
  height: 62vh;
  min-height: 380px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: #eef2f5;      /* the pale ground tiles fade into while loading */
}
.leaflet-container { font: inherit; }

.map-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .3rem .7rem;
  font-size: .74rem;
  color: var(--muted);
  padding: .5rem .2rem 0;
}
.map-legend .legend-label { text-transform: uppercase; letter-spacing: .05em; }
.map-legend .key { display: inline-flex; align-items: center; gap: .3rem; }
.map-legend .key i {
  width: .6rem; height: .6rem;
  border-radius: 50%;
  border: 1px solid #fff;
  box-shadow: 0 0 0 1px rgba(0,0,0,.12);
}
.map-legend .legend-note { margin-left: auto; }

/* hover card */
.maptip-wrap .leaflet-tooltip-content { margin: 0; }
.maptip-wrap { cursor: pointer; }
.maptip-wrap:hover { border-color: var(--accent); }
.maptip-wrap {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 4px 14px rgba(29, 58, 95, .16);
  padding: .5rem .6rem;
  color: var(--ink);
}
.maptip-wrap::before { display: none; }     /* Leaflet's arrow, not our shape */
.maptip b { font-size: .92rem; }
.maptip .tip-state { color: var(--muted); font-size: .78rem; }
.maptip .tip-overall { font-size: .82rem; font-weight: 600; margin: .15rem 0 .3rem; }
.maptip table { border-collapse: collapse; font-size: .76rem; }
.maptip td { padding: .05rem .5rem .05rem 0; color: var(--muted); white-space: nowrap; }
.maptip td:last-child { color: var(--ink); }
.maptip .chip {
  display: inline-block;
  width: .5rem; height: .5rem;
  border-radius: 2px;
  margin-right: .3rem;
}
.maptip .tip-hint {
  margin-top: .35rem;
  font-size: .68rem;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: .04em;
}

#map-detail { margin-top: .8rem; }
#map-detail .resort { margin-bottom: 0; }

@media (max-width: 520px) {
  #map { height: 52vh; }
}

/* Attribution: present and complete, but folded away — CC BY asks for credit,
   not for a wall of text under every forecast. */
.licences { max-width: 44rem; margin: .6rem auto 0; text-align: left; }
.licences summary {
  cursor: pointer;
  text-align: center;
  color: var(--muted);
  font-size: .78rem;
}
.licences summary:hover { color: var(--accent); }
.licences p { font-size: .74rem; line-height: 1.5; color: var(--muted); }
.licences a { color: var(--accent); }

footer .contact { margin: .5rem 0 0; }
footer .contact a { color: var(--accent); font-size: .85rem; }

/* "Map" pill on a result row — quieter than the expander beside it, since
   opening the detail is the primary action and this is the alternative. */
.mapbtn {
  display: inline-flex;
  align-items: center;
  gap: .25rem;
  font: inherit;
  font-size: .78rem;
  font-weight: 600;
  padding: .2rem .55rem;
  border-radius: 999px;
  background: var(--paper);
  border: 1px solid var(--line);
  color: var(--muted);
  cursor: pointer;
}
.mapbtn:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
.mapbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---- best-value trips ---------------------------------------------------- */
/* A refinement of "I'm flexible", so it sits indented under that radio rather
   than reading as a third option. */
.value-opts { margin: .5rem 0 0 .2rem; padding-left: .8rem;
              border-left: 2px solid var(--rule, #dcdcd8); }
.value-toggle { display: block; font-size: .92rem; margin-bottom: .4rem; }
.value-opts .constraints { margin-top: .5rem; }

/* The sentence the feature exists to produce. Given its own line under the
   head rather than squeezed into the badge row, because it is prose and the
   badges are chips. */
.value-line { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap;
              padding: .35rem .95rem .5rem; font-size: .86rem;
              color: var(--ink); }
.value-line strong { font-weight: 600; }
.value-period { font-size: .78rem; opacity: .7; }
.badge.window { background: #eef2f7; color: #33465e; }

@media (max-width: 480px) {
  .value-line { padding: .3rem .75rem .45rem; font-size: .8rem; }
  .value-opts .constraints { gap: .45rem .8rem; }
}



/* The season charts are the densest thing on a card, so they sit behind a
   disclosure. <details> gives keyboard and screen-reader support for free. */
.season-details > summary { cursor: pointer; list-style: none; }
.season-details > summary::-webkit-details-marker { display: none; }
.season-details > summary h4 { display: inline-block; margin: .7rem 0 .3rem; }
.season-details > summary h4::after { content: " ›"; opacity: .55; }
.season-details[open] > summary h4::after { content: " ⌄"; }
.season-details > summary:focus-visible { outline: 2px solid var(--accent);
                                          outline-offset: 2px; border-radius: 3px; }

/* ---- book travel --------------------------------------------------------- */
/* Only the route line for now; the CTA and its styles return with the
   booking partner. */

/* ---- getting there: routed airport -> resort journeys ---- */
.routetable {
  border-collapse: collapse;
  width: 100%;
  margin: .3rem 0 .5rem;
  font-size: .88rem;
}
.routetable td {
  padding: .3rem .5rem .3rem 0;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}
.routetable tr:last-child td { border-bottom: none; }
.rmode { width: 1.5rem; font-size: 1rem; line-height: 1.2; }
.rport { white-space: nowrap; }
.rport .apname { color: var(--muted); font-weight: 400; }
/* tabular-nums so "1 h 08" and "52 min" line up down the column */
.rtime {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--ink);
}
.rhow { color: var(--muted); }
.rhow .via {
  display: block;
  font-size: .82rem;
  opacity: .85;
  /* Rail summaries like "EC 191 > REX 25923 > RJX 19917" can outrun a phone;
     let them scroll in their own box rather than widen the card. */
  overflow-x: auto;
  white-space: nowrap;
}
.routefoot { margin-top: .2rem; font-size: .8rem; }

/* The airport end of the journey. A plain glyph in a ring rather than a
   Leaflet default pin, which would read as another resort. */
.airport-pin {
  background: var(--card);
  border: 2px solid var(--route);
  border-radius: 50%;
  text-align: center;
  line-height: 22px;
  font-size: .8rem;
  box-shadow: 0 1px 3px rgba(0,0,0,.35);
}
.roadnote { margin: .1rem 0 .2rem; color: var(--bad); font-size: .82rem; }

/* ---- attribute match grid ----
   Two channels on purpose, so they can never be read as one:
     track LENGTH = how strongly this resort rates the attribute
     colour/ring  = whether the reader asked for it
   Deliberately NOT the five score-band colours — those mean "how good is this
   for you" everywhere else, and these describe a mountain rather than judging
   it.

   The measurement is a TRACK along the bottom edge, not a fill behind the
   label. Two reasons, both learned the hard way: a background fill at 100%
   has no edge to see, so a full bar looked identical to an empty one; and a
   filled box with a divider and a tick on the right reads as a text input
   with a button, not as data. */
.attrgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
  gap: .3rem;
  margin: .35rem 0 .3rem;
}
.attr {
  position: relative;
  display: flex;
  align-items: center;
  gap: .3rem;
  padding: .25rem .5rem .5rem;
  /* No border by default. A bordered box with a tick on the right is the
     visual language of a checkbox, and these are readouts, not controls —
     the first version invited clicks that do nothing. */
  border: 1px solid transparent;
  border-radius: 5px;
  background: var(--paper);
  font-size: .78rem;
  color: var(--muted);
  min-width: 0;
}
.attrname { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* The same reading the track gives, as one glyph, for scanning rather than
   measuring. Greyscale on purpose: it describes the mountain, and every
   colour on this card already means "how good is this for you". Intensity
   follows the rating so a row of these reads at a glance. */
.attrmark {
  margin-left: auto;
  flex: none;
  font-size: .8rem;
  line-height: 1;
  font-weight: 700;
}
.attrmark.hi  { color: #454f57; }
.attrmark.mid { color: #8a939b; }
.attrmark.lo  { color: #bcc3c9; font-weight: 400; }
.attrtrack {
  position: absolute;
  left: .5rem; right: .5rem; bottom: .25rem;
  height: 3px;
  border-radius: 2px;
  background: #e6ebf0;
  overflow: hidden;
}
.attrtrack i {
  display: block;
  height: 100%;
  width: var(--fill, 0%);
  border-radius: 2px;
  background: #94a9bc;
}

/* Asked for. Ring, tint and a tick — three cues, so it survives printing and
   does not depend on telling two blues apart. */
.attr.on {
  border-color: var(--accent);
  color: var(--ink);
  font-weight: 600;
  background: #f4f9fe;
}
.attr.on .attrtrack i { background: var(--accent); }

.attrlegend { margin-top: .1rem; font-size: .78rem; }

@media (max-width: 480px) {
  .attrgrid { grid-template-columns: repeat(auto-fit, minmax(7.2rem, 1fr)); }
  .attr { font-size: .74rem; }
}
