/*
 * region-card.njk in two contexts (DESIGN.md § "Region card"):
 *   .region-card--infographic — fixed-height, used in the wide-viewport grid around the map
 *   .region-card--carousel    — natural height, used in the narrow-viewport scroll-snap row
 * Both: name + rent header, Korean name, blurb, vibe tags, then an "Open <region> →" row on a
 * hairline. The whole card highlights on hover; the footer row is the real <a href>.
 */
.region-card {
  display: flex;
  flex-direction: column;
  padding: 14px 16px;
  border: 1px solid var(--color-border);
  border-radius: 10px;
  background: var(--color-bg);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

/* Pointer devices get a hover/focus border (the wide infographic's card↔map cross-highlight).
   On a phone the card body has no interactive state of its own — the green border there comes
   only from a map tap (.region-card--selected, set by region-card.js). */
@media (hover: hover) {
  .region-card:hover,
  .region-card:focus-within {
    border-color: var(--color-primary);
  }

  /* An ineligible region's card has no green anywhere else on it — korea-map.js only toggles
     href/aria-disabled on the inner .region-card__link (there's no .region-card--ineligible
     class), so this reads that attribute via :has() instead of needing a JS-added class. Muted
     grey, not the eligible-state green, since hovering it isn't really "activating" anything. */
  .region-card:hover:has(.region-card__link[aria-disabled="true"]),
  .region-card:focus-within:has(.region-card__link[aria-disabled="true"]) {
    border-color: var(--color-text-muted);
  }
}

.region-card--selected {
  border-color: var(--color-primary);
}

/* Same muted-not-green exception as the :hover rule above, for the tap-selected state — a map
   tap on an ineligible region (region-card.js) shouldn't border its card in the eligible-state
   green either. */
.region-card--selected:has(.region-card__link[aria-disabled="true"]) {
  border-color: var(--color-text-muted);
}

.region-card__header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.region-card__name {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
  /* keep-all/overflow-wrap on .region-card__name-ko below are the mixed-script wrap fix; no
     text-wrap: pretty here — it moved whole words to the next line even when they fit on
     multi-word titles elsewhere (see region-page.css), so it's not used anywhere on the site. */
}

.region-card__rent {
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
}

.region-card__name-ko {
  margin: 2px 0 8px;
  font-family: var(--font-family-ko);
  font-weight: 400;
  font-size: 12px;
  color: var(--color-text-muted);
  word-break: keep-all;
  overflow-wrap: break-word;
}

.region-card__intro {
  /* 11px matches the gap below the vibe-tag row (.region-card__link margin-top) so the tags sit
     with symmetric space above and below. */
  margin: 0 0 11px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--color-text-soft);
}

.region-card__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
}

/* Vibe-tag pill, small size (DESIGN.md § Vibe tag) — shared with .city-card__tags li. Same
   fill/border/text as the region-page header pill, one size down for the card grids. */
.region-card__tags li {
  padding: 4px 10px;
  border: 1px solid var(--color-primary-tint-border);
  border-radius: 22px;
  background: var(--color-vibe-tag-bg);
  color: var(--color-primary-dark);
  font-size: 13px;
  font-weight: 500;
  line-height: 1.2;
  white-space: nowrap;
}

.region-card__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 11px;
  padding-top: 9px;
  border-top: 1px solid var(--color-border-soft);
  font-size: 13px;
  font-weight: 500;
  color: var(--color-primary);
  text-decoration: none;
}

.region-card__link:hover,
.region-card__link:focus-visible {
  text-decoration: underline;
}

/* Phone: grow the row's hit area to >=44px with padding — the text and hairline sit where the
   design puts them, only the tap target is bigger (DESIGN.md § Accessibility). */
@media (max-width: 767.98px) {
  .region-card__link {
    padding-top: 12px;
    padding-bottom: 11px;
  }

  /* Without this, the carousel card's own 14px padding-bottom stacks underneath the link's
     padding-bottom above, so "Open <region> →" sits 25px above the card's bottom edge but only
     12px below the hairline — visibly lopsided. Trim the card's share to just the difference
     (14 - 11) so the two paddings combine back to 14px, matching the card's top padding instead
     of doubling up on the link's. */
  .region-card--carousel {
    padding-bottom: 3px;
  }
}

/* Gated the same way as the map shape (korea-map.js) — href removed, so this is already inert;
   the muted colour + no-pointer-events just stop it from looking clickable. */
.region-card__link[aria-disabled="true"] {
  color: var(--color-text-muted);
  pointer-events: none;
  cursor: default;
  text-decoration: none;
}

/* Lets the name concede space to a rent figure (region-card__rent, white-space: nowrap, never
   truncated — it's a number) rather than overflowing the card's fixed width: without min-width:0
   here, .region-card__header's flex children can't shrink past their own content size, and
   Gangwon-do's "Gangwon-do ₩1–1.4M/mo" bled past the card's right edge into its tablet-carousel
   neighbour (262px cards, region-card.css tablet band). Applies to both variants — the
   infographic width has always had room, but nothing stopped this at the narrower carousel width. */
.region-card__name {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* Every region's full vibe-tag list from data, same as the region page and the carousel — no
   count cap. They fit on one line at the infographic card width; wrap is the safety net, not
   the norm (re-check card centres for the leader lines if a tag list grows past one row). */
.region-card--infographic .region-card__tags {
  gap: 4px;
}

.region-card--infographic .region-card__tags li {
  flex-shrink: 0;
  white-space: nowrap;
}

/* Carousel (narrow) variant. Height comes from content and is equalised across a row by the
   track's `align-items: stretch` (default) — never a hard `height`, which made a card shorter
   than its own content at 262px and spilled it past the bottom edge. */
/* .region-carousel__item is a row-direction flex container (single child) — its default
   align-items:stretch only stretches the cross axis (height); width is left to the card's own
   flex-grow, which defaults to 0. Without width:100% here the card sizes to its own max-content
   instead of the item's fixed width (262px in the tablet band), and a wide header (e.g.
   Gangwon-do's rent figure) or tag row overflows past the card's own right edge into the next
   one. min-width:0 lets it actually shrink there too, not just grow up to 100%. */
.region-card--carousel {
  width: 100%;
  min-width: 0;
}

/* auto, not the fixed 11px above: pins the link to the card's own bottom edge regardless of how
   much intro/tag content sits above it, so "Open <region> →" lands at the same row across a
   track-stretched carousel row (all cards in a row already share one height via align-items:
   stretch — without this, a card with less text above just left blank space below its own link
   instead of the link landing lower to match). Scoped to the carousel: the infographic variant's
   cards size to their own content with no extra height to distribute, so `auto` there resolved to
   0 and collapsed the fixed gap above the hairline instead of doing nothing as intended. */
.region-card--carousel .region-card__link {
  margin-top: auto;
}

/* Wrap, not nowrap: a fixed-width card can't guarantee every region's tag row fits on one line
   forever (data-driven, CLAUDE.md — the layout adapts to _data/regions.json, never the
   reverse). The tablet-band width below is sized so today's widest set (Gangwon-do's four tags)
   still fits on one line in the common case; wrap is the safety net if that ever changes, same
   principle as the infographic variant's tag row. */
.region-card--carousel .region-card__tags {
  flex-wrap: wrap;
  /* Floor for the gap above the hairline: .region-card__link's margin-top is `auto` in this
     variant (pushes the link to the stretched card's bottom edge), which resolves to 0 — not
     the usual 11px — when the card's own content already fills the row's stretched height, e.g.
     Gyeonggi-do's three-line intro. This reserves the 11px as fixed space so the auto margin can
     only add MORE on top of it, never less. */
  margin-bottom: 11px;
}

/*
 * ── Homepage "The six regions" section ────────────────────────────────────────────────────
 */
.home-regions {
  max-width: var(--content-max-width);
  margin-inline: auto;
  /* Landing spot for the "Regions" nav link / hero scroll cue (both target #map) — leaves a
     little air above the heading instead of jamming it against the viewport top. */
  scroll-margin-top: var(--space-5);
}

.home-regions__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px 24px;
  margin-bottom: 18px;
}

.home-regions__intro h2 {
  margin: 0 0 6px;
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.015em;
}

.home-regions__intro p {
  margin: 0;
  max-width: 54ch;
  font-size: 15px;
  color: var(--color-text-muted);
}

/* Wide-viewport copy runs a few characters past 54ch, orphaning "region." onto its own line
   even though the row has room; give it a wider cap so the sentence fits on one line.
   (Selector matches .home-regions__intro p's specificity so it actually overrides it.) */
.home-regions__intro p.home-regions__lead--wide {
  max-width: 60ch;
}

/* The map interaction copy differs by input: hover wording only where the infographic (and its
   cross-hover) is live, tap wording everywhere below it — hover can't be assumed at 900 and no
   infographic is drawn there. */
.home-regions__lead--narrow {
  display: none;
}

@media (max-width: 1023.98px) {
  .home-regions__lead--wide {
    display: none;
  }

  .home-regions__lead--narrow {
    display: block;
  }
}

.home-regions__source {
  margin-top: 20px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--color-text-muted);
}

/*
 * Region-info shell (ARCHITECTURE.md): mobile-first — the map (a child of
 * .region-infographic) stays visible at every width; the two flanking columns and their leader
 * lines are wide-viewport-only, and below the breakpoint the .region-carousel takes over.
 */
.region-infographic {
  position: relative;
}

.region-infographic__col,
.region-infographic__lines {
  display: none;
}

/* Narrow-viewport carousel — breaks out of .page's padding so cards can scroll to the screen
   edge, with its own inner track padding. Hidden at >=1024px (--bp-region-info-wide). */
.region-carousel {
  margin: 12px calc(var(--space-4) * -1) 0;
}

/* ul.* — base.css's `ul[class] { padding: 0 }` reset ties with a bare class and would otherwise
   zero the track's side padding, so the first/last card would touch the screen edge. */
ul.region-carousel__track {
  display: flex;
  gap: 12px;
  padding: 0 var(--space-4);
  scroll-padding-inline: var(--space-4);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.region-carousel__track::-webkit-scrollbar {
  display: none;
}

.region-carousel__item {
  display: flex;
  /* ~88% of the viewport (capped) so a peek of the next card shows and all four vibe tags fit
     on one line. vw (not %) so it's a fraction of the screen, not of the padding-inset track. */
  flex: 0 0 88vw;
  max-width: 360px;
  scroll-snap-align: start;
}

/* ol.* — see the ul.region-carousel__track note; `ol[class] { margin: 0 }` would otherwise
   zero this, leaving the dots flush against the cards. */
ol.region-carousel__dots {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin-top: 16px;
}

.region-carousel__dots li {
  width: 5px;
  height: 5px;
  border-radius: 3px;
  background: var(--color-border);
}

/* No-JS fallback: first dot lit. region-card.js adds .region-carousel--synced and then tracks
   scroll position with .is-active instead. */
.region-carousel__dots li:first-child {
  width: 20px;
  background: var(--color-primary);
}

.region-carousel--synced .region-carousel__dots li:first-child {
  width: 5px;
  background: var(--color-border);
}

.region-carousel--synced .region-carousel__dots li.is-active {
  width: 20px;
  background: var(--color-primary);
}

/* Tablet band (768–1023): the infographic hasn't kicked in yet, so the carousel is the layout.
   The map is capped and centred above it, the cards keep a fixed width (300px — wide enough for
   Gangwon-do's four vibe tags on one line without the header/tags row ever overflowing into the
   next card) so ~3 show with the next clipped, and the dots come off — a row that shows 2+ cards
   can't map onto per-card dots (DESIGN.md § Mobile), and the clipped card is its own affordance.
   Phone (<768) is untouched. */
@media (min-width: 768px) and (max-width: 1023.98px) {
  .region-carousel__item {
    flex-basis: 300px;
    max-width: 300px;
  }

  /* ol.* to outrank base.css's `ol[class]` / the base ol.region-carousel__dots flex rule. */
  ol.region-carousel__dots {
    display: none;
  }
}

@media (min-width: 1024px) {
  .region-carousel {
    display: none;
  }

  /*
   * Fills the full .home-regions width (capped at --content-max-width) so the card columns line
   * up with the section heading and source line, matching the design reference. The 30:44:30
   * `fr` ratio holds as it scales; the map/leader-line SVGs (viewBox-scaled, width:100%) track
   * it. `min-width: 0` on the flanking columns is load-bearing — grid tracks won't otherwise
   * shrink past their content's intrinsic min-content width. index.njk's leader-line viewBox
   * (0 0 1000 950) is calibrated to the ~1200px full-width layout (left column ≈ 33% wide); it
   * activates from 1024 and drifts a little toward the narrow end — Jeju's leader is dropped
   * 1024–1149 for that reason (see the media query at the foot of this file).
   */
  .region-infographic {
    display: grid;
    grid-template-columns: 30fr 44fr 30fr;
    column-gap: 20px;
    align-items: center;
    width: 100%;
  }

  .region-infographic__col {
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-width: 0;
  }

  .region-infographic__lines {
    display: block;
    position: absolute;
    grid-column: 1 / -1;
    grid-row: 1 / 2;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 0;
  }

  /* Map stacks above the lines layer so they read as passing under the land, not over labels.
     The 420fr grid column governs its width here, so drop the standalone cap/centring. */
  .korea-map {
    position: relative;
    z-index: 1;
    min-width: 0;
    max-width: none;
    margin-inline: 0;
  }

  .region-infographic__lines line {
    stroke: var(--color-text-muted);
    stroke-width: 1.5;
    stroke-opacity: 0.6;
    transition: stroke 0.15s ease, stroke-width 0.15s ease, stroke-opacity 0.15s ease;
  }

  /* Cross-hover: hovering/focusing a map region highlights its card too. */
  .region-infographic:has(.region[data-slug="gyeonggi-do"]:hover) [data-region-slug="gyeonggi-do"],
  .region-infographic:has(.region[data-slug="gangwon-do"]:hover) [data-region-slug="gangwon-do"],
  .region-infographic:has(.region[data-slug="chungcheong-do"]:hover) [data-region-slug="chungcheong-do"],
  .region-infographic:has(.region[data-slug="gyeongsang-do"]:hover) [data-region-slug="gyeongsang-do"],
  .region-infographic:has(.region[data-slug="jeolla-do"]:hover) [data-region-slug="jeolla-do"],
  .region-infographic:has(.region[data-slug="jeju-do"]:hover) [data-region-slug="jeju-do"],
  .region-infographic:has(.region[data-slug="gyeonggi-do"]:focus-visible) [data-region-slug="gyeonggi-do"],
  .region-infographic:has(.region[data-slug="gangwon-do"]:focus-visible) [data-region-slug="gangwon-do"],
  .region-infographic:has(.region[data-slug="chungcheong-do"]:focus-visible) [data-region-slug="chungcheong-do"],
  .region-infographic:has(.region[data-slug="gyeongsang-do"]:focus-visible) [data-region-slug="gyeongsang-do"],
  .region-infographic:has(.region[data-slug="jeolla-do"]:focus-visible) [data-region-slug="jeolla-do"],
  .region-infographic:has(.region[data-slug="jeju-do"]:focus-visible) [data-region-slug="jeju-do"] {
    border-color: var(--color-primary);
    box-shadow: var(--shadow-md);
  }

  /* Same muted-not-green override as the card's own :hover above, for the reverse direction —
     hovering an ineligible region's map shape shouldn't highlight its card in the eligible-state
     green either. More specific than the block above (adds .region--ineligible on the source
     side), so it wins regardless of source order. */
  .region-infographic:has(.region--ineligible[data-slug="gyeonggi-do"]:hover) [data-region-slug="gyeonggi-do"],
  .region-infographic:has(.region--ineligible[data-slug="gangwon-do"]:hover) [data-region-slug="gangwon-do"],
  .region-infographic:has(.region--ineligible[data-slug="chungcheong-do"]:hover) [data-region-slug="chungcheong-do"],
  .region-infographic:has(.region--ineligible[data-slug="gyeongsang-do"]:hover) [data-region-slug="gyeongsang-do"],
  .region-infographic:has(.region--ineligible[data-slug="jeolla-do"]:hover) [data-region-slug="jeolla-do"],
  .region-infographic:has(.region--ineligible[data-slug="jeju-do"]:hover) [data-region-slug="jeju-do"],
  .region-infographic:has(.region--ineligible[data-slug="gyeonggi-do"]:focus-visible) [data-region-slug="gyeonggi-do"],
  .region-infographic:has(.region--ineligible[data-slug="gangwon-do"]:focus-visible) [data-region-slug="gangwon-do"],
  .region-infographic:has(.region--ineligible[data-slug="chungcheong-do"]:focus-visible) [data-region-slug="chungcheong-do"],
  .region-infographic:has(.region--ineligible[data-slug="gyeongsang-do"]:focus-visible) [data-region-slug="gyeongsang-do"],
  .region-infographic:has(.region--ineligible[data-slug="jeolla-do"]:focus-visible) [data-region-slug="jeolla-do"],
  .region-infographic:has(.region--ineligible[data-slug="jeju-do"]:focus-visible) [data-region-slug="jeju-do"] {
    border-color: var(--color-text-muted);
  }

  /* Leader-line highlight, triggered from either end. */
  .region-infographic:has([data-region-slug="gyeonggi-do"]:hover) .region-infographic__lines line[data-slug="gyeonggi-do"],
  .region-infographic:has([data-region-slug="gyeonggi-do"]:focus-within) .region-infographic__lines line[data-slug="gyeonggi-do"],
  .region-infographic:has(.region[data-slug="gyeonggi-do"]:hover) .region-infographic__lines line[data-slug="gyeonggi-do"],
  .region-infographic:has(.region[data-slug="gyeonggi-do"]:focus-visible) .region-infographic__lines line[data-slug="gyeonggi-do"],
  .region-infographic:has([data-region-slug="gangwon-do"]:hover) .region-infographic__lines line[data-slug="gangwon-do"],
  .region-infographic:has([data-region-slug="gangwon-do"]:focus-within) .region-infographic__lines line[data-slug="gangwon-do"],
  .region-infographic:has(.region[data-slug="gangwon-do"]:hover) .region-infographic__lines line[data-slug="gangwon-do"],
  .region-infographic:has(.region[data-slug="gangwon-do"]:focus-visible) .region-infographic__lines line[data-slug="gangwon-do"],
  .region-infographic:has([data-region-slug="chungcheong-do"]:hover) .region-infographic__lines line[data-slug="chungcheong-do"],
  .region-infographic:has([data-region-slug="chungcheong-do"]:focus-within) .region-infographic__lines line[data-slug="chungcheong-do"],
  .region-infographic:has(.region[data-slug="chungcheong-do"]:hover) .region-infographic__lines line[data-slug="chungcheong-do"],
  .region-infographic:has(.region[data-slug="chungcheong-do"]:focus-visible) .region-infographic__lines line[data-slug="chungcheong-do"],
  .region-infographic:has([data-region-slug="gyeongsang-do"]:hover) .region-infographic__lines line[data-slug="gyeongsang-do"],
  .region-infographic:has([data-region-slug="gyeongsang-do"]:focus-within) .region-infographic__lines line[data-slug="gyeongsang-do"],
  .region-infographic:has(.region[data-slug="gyeongsang-do"]:hover) .region-infographic__lines line[data-slug="gyeongsang-do"],
  .region-infographic:has(.region[data-slug="gyeongsang-do"]:focus-visible) .region-infographic__lines line[data-slug="gyeongsang-do"],
  .region-infographic:has([data-region-slug="jeolla-do"]:hover) .region-infographic__lines line[data-slug="jeolla-do"],
  .region-infographic:has([data-region-slug="jeolla-do"]:focus-within) .region-infographic__lines line[data-slug="jeolla-do"],
  .region-infographic:has(.region[data-slug="jeolla-do"]:hover) .region-infographic__lines line[data-slug="jeolla-do"],
  .region-infographic:has(.region[data-slug="jeolla-do"]:focus-visible) .region-infographic__lines line[data-slug="jeolla-do"],
  .region-infographic:has([data-region-slug="jeju-do"]:hover) .region-infographic__lines line[data-slug="jeju-do"],
  .region-infographic:has([data-region-slug="jeju-do"]:focus-within) .region-infographic__lines line[data-slug="jeju-do"],
  .region-infographic:has(.region[data-slug="jeju-do"]:hover) .region-infographic__lines line[data-slug="jeju-do"],
  .region-infographic:has(.region[data-slug="jeju-do"]:focus-visible) .region-infographic__lines line[data-slug="jeju-do"] {
    stroke: var(--color-primary-dark);
    stroke-width: 2.5;
    stroke-opacity: 1;
  }
}

/* 1024–1149: the card columns run taller than the map, so the leader layer (viewBox calibrated
   at ~1200) drifts. Every line but Jeju's keeps enough slack; Jeju's island is tiny and its
   endpoint lands ~15–55px outside it. Drop that one line in this range — the island already
   prints "Jeju-do" — and let it back in at 1150+ where it lands true again. */
@media (min-width: 1024px) and (max-width: 1149.98px) {
  .region-infographic__lines line[data-slug="jeju-do"] {
    display: none;
  }
}
