/* ==========================================================================
   Nymölla Skog – components
   Reusable UI pieces shared across sections. Filled in step by step.
   ========================================================================== */

/* ---- Buttons (primary, secondary, header) ---- */

.ns-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-button);
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--dur-base) var(--ease-out), color var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}

.ns-btn__inner {
  display: inline-flex;
  align-items: center;
  gap: 9px;
}

/* Header "Kontakta oss" pill */
.ns-btn--header {
  height: var(--header-btn-height);
  padding-inline: clamp(20px, 17.46px + 0.705vw, 31px) clamp(20px, 17.23px + 0.769vw, 32px);
  background: var(--ns-beige-light);
  color: var(--ns-green-dark);
  font-size: var(--fs-ui);
}

@media (max-width: 767px) {
  /* The phone icon's bottom curve was getting clipped by the pill's
     overflow: hidden at small sizes — 2px of extra room fixes it. */
  .ns-btn--header {
    height: calc(var(--header-btn-height) + 5px);
  }
}

.ns-btn--header .ns-btn__inner {
  gap: clamp(5px, 4.08px + 0.256vw, 9px);
}

.ns-btn--header .ns-btn__icon {
  width: clamp(12px, 10.62px + 0.385vw, 18px);
  height: clamp(12px, 10.85px + 0.321vw, 25px);
}

.ns-btn--header:hover,
.ns-btn--header:focus-visible {
  background: var(--ns-rust);
  color: var(--ns-white);
}

/* Header "Mätningsbestämmelser" pill — outlined, same trail hover as the
   hero secondary "Läs mer om oss" button (button-fx.css). */
.ns-btn--header-outline {
  height: var(--header-btn-height);
  padding-inline: clamp(20px, 17.46px + 0.705vw, 31px);
  background: transparent;
  border: var(--border-btn-secondary) solid rgb(255 255 255 / 0.2);
  color: var(--ns-beige-light);
  font-size: var(--fs-ui);
  --ns-btn-border: var(--border-btn-secondary);
}

@media (max-width: 767px) {
  .ns-btn--header-outline {
    height: calc(var(--header-btn-height) + 5px);
    border-width: 1px;
    --ns-btn-border: 1px;
  }

  /* Both header buttons don't fit on mobile — only "Mätningsbestämmelser"
     stays visible there, per PM feedback. */
  .ns-header__contact-btn {
    display: none;
  }
}

/* Hero primary button */
.ns-btn--primary {
  height: var(--btn-height);
  padding-inline: var(--btn-padding-x);
  background: var(--ns-rust);
  color: var(--ns-beige-light);
}

.ns-btn--primary:hover,
.ns-btn--primary:focus-visible {
  background: var(--ns-beige-dark);
  color: var(--ns-green);
}

/* Hero secondary button */
.ns-btn--secondary {
  height: var(--btn-height);
  padding-inline: 34px;
  background: transparent;
  border: var(--border-btn-secondary) solid rgb(255 255 255 / 0.2);
  color: var(--ns-beige-light);
  --ns-btn-border: var(--border-btn-secondary);
}

@media (max-width: 767.98px) {
  .ns-btn--primary,
  .ns-btn--secondary {
    width: 100%;
  }

  .ns-btn--secondary {
    border-width: 1px;
    --ns-btn-border: 1px;
  }
}

/* ---- Tags (area filter pills) ---- */

.ns-tag {
  height: var(--tag-height);
  padding-inline: var(--tag-padding-x);
  border-radius: var(--radius-pill);
  border: var(--border-tag) solid var(--ns-beige-deep);
  background: var(--ns-white);
  color: var(--ns-green-dark);
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--fs-ui);
  line-height: var(--lh-ui);
  text-align: center;
  white-space: nowrap;
  transition: background-color var(--dur-base) var(--ease-out), color var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out);
}

.ns-tag:hover,
.ns-tag:focus-visible {
  background: var(--color-intro-bg);
}

.ns-tag[aria-pressed="true"] {
  background: var(--ns-green);
  border-color: var(--ns-white);
  color: var(--ns-white);
}

/* ---- Map pins (active, coming soon, selected + pulse) ---- */

.ns-pin-hit {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  cursor: pointer;
  position: relative;
  /* Counteracts .ns-map__gmap's muting filter (sections.css) so the pins keep
     their exact token colours instead of inheriting the duller base map. */
  filter: brightness(1.111) saturate(1.333);
}

.ns-pin {
  position: relative;
  width: var(--pin-size);
  height: var(--pin-size);
  border-radius: 50%;
  background: var(--ns-green);
  z-index: 1;
}

.ns-pin__dot {
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--pin-dot);
  height: var(--pin-dot);
  border-radius: 50%;
  background: var(--color-intro-bg);
  transform: translate(-50%, -50%);
}

.ns-pin--soon {
  background: var(--ns-rust);
  opacity: var(--pin-soon-opacity);
}

/* PM override (25 Sep 2026): the "Här finns vi" pin stays full-opacity
   brown so it reads as distinct from the other muted "soon" pins. */
.ns-pin--highlight {
  opacity: 1;
}

.ns-pin--selected {
  z-index: 2;
}

.ns-pin--selected::before,
.ns-pin--selected::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  border-radius: 50%;
  background: var(--ns-green);
  transform: translate(-50%, -50%);
  pointer-events: none;
}

.ns-pin--selected::before {
  width: var(--pin-ring-1);
  height: var(--pin-ring-1);
  opacity: var(--pin-ring-1-opacity);
}

.ns-pin--selected::after {
  width: var(--pin-ring-2);
  height: var(--pin-ring-2);
  opacity: var(--pin-ring-2-opacity);
}

/* Pulse (ported from HNP's start-page play-button rings, see PROGRESS.md):
   two pseudo-elements growing + fading from their own static frame, the
   second delayed. Reduced motion keeps the static frame above, unanimated. */
@media (prefers-reduced-motion: no-preference) {
  .ns-pin--selected::before,
  .ns-pin--selected::after {
    animation: ns-pin-pulse 2.4s var(--ease-out) infinite;
  }

  .ns-pin--selected::after {
    animation-delay: 0.75s;
  }
}

@keyframes ns-pin-pulse {
  0% {
    transform: translate(-50%, -50%) scale(0.7);
    opacity: var(--pin-ring-1-opacity);
  }

  70% {
    transform: translate(-50%, -50%) scale(1.3);
    opacity: 0;
  }

  100% {
    transform: translate(-50%, -50%) scale(1.35);
    opacity: 0;
  }
}

/* ---- "Kommer snart" shared tooltip (map pins + footer social icons) ---- */

.ns-soon-tip {
  position: fixed;
  z-index: 1000;
  background: var(--ns-green-dark);
  color: var(--ns-beige-light);
  font-family: var(--font-body);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-ui);
  line-height: 1.2;
  padding: 8px 16px;
  border-radius: var(--radius-pill);
  white-space: nowrap;
  box-shadow: var(--shadow-tooltip);
  opacity: 0;
  transform: translateY(4px) scale(0.96);
  transition: opacity 120ms var(--ease-out), transform 120ms var(--ease-out);
  pointer-events: none;
}

.ns-soon-tip.is-visible {
  opacity: 1;
  transform: translateY(0) scale(1);
  transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}

.ns-soon-tip__arrow {
  position: absolute;
  bottom: -4px;
  width: 8px;
  height: 8px;
  background: var(--ns-green-dark);
  transform: rotate(45deg);
}

.ns-soon-tip--flip .ns-soon-tip__arrow {
  bottom: auto;
  top: -4px;
}

/* ---- Contact card (selected + empty state) ---- */

.ns-map__card-panel {
  /* Both panels are grid-stacked in the same cell (grid-area: 1/1) rather
     than position:absolute — the card needs to auto-size to whichever
     panel is taller (see ".ns-map__card" below), and an absolutely
     positioned child contributes nothing to a parent's auto/content height,
     which is what originally forced the card to a hand-picked min-height
     that didn't track the photo/info's real size at every breakpoint. */
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-fast) var(--ease-out);
}

.ns-map__card[data-state="empty"] .ns-map__card-panel--empty,
.ns-map__card[data-state="contact"] .ns-map__card-panel--contact {
  opacity: 1;
  visibility: visible;
}

/* Empty state ("Välj ett område") */
.ns-map__card-panel--empty {
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 24px;
  background: var(--color-intro-bg);
  color: var(--ns-green);
}

.ns-map__card-icon {
  width: 32px;
  height: 43px;
}

.ns-map__card-empty-title {
  margin-top: 20px;
  font-family: var(--font-heading);
  font-weight: var(--fw-regular);
  font-size: var(--fs-empty-title);
  line-height: var(--lh-empty-title);
  letter-spacing: var(--tracking-heading);
}

.ns-map__card-empty-body {
  max-width: 300px;
  margin-top: 12px;
  color: var(--color-text);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
}

/* Contact state ("Kontaktperson") */
.ns-map__card-panel--contact {
  background: var(--ns-green);
  color: var(--color-on-dark);
}

.ns-map__card-photo {
  position: relative;
  flex: 0 0 auto;
  /* Aspect-ratio (not a flat 191px) so the photo scales with the card's own
     width instead of only reading correctly at the exact 316px mobile card
     width — a flat height made it look flattened/too-wide once the card
     grows to the full row width (e.g. 657px at 768px) while still stacked
     in a single column below 1024px. Capped with max-height: below 1024px
     the map box stays a fixed 324px tall (sections.css) regardless of
     width, so letting the photo's aspect-ratio grow unbounded with the
     row's full width made the card balloon far taller than the map next to
     it (e.g. ~582px at 768px) — capping keeps the photo (and so the whole
     card) closer to the map's own height, only cropping in a bit more via
     object-fit: cover beyond that width instead of growing indefinitely. */
  aspect-ratio: 316 / 191;
  width: 100%;
  height: auto;
  max-height: 360px;
  background: var(--color-intro-bg);
  overflow: hidden;
}

.ns-map__card-photo picture,
.ns-map__card-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--ns-photo-position, 50% 50%);
}

.ns-map__card-photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgb(26 46 42 / 0.1); /* mobile PSD tint */
}

@media (min-width: 1024px) {
  .ns-map__card-photo::after {
    background: var(--photo-tint); /* desktop PSD tint (8%) */
  }
}

.ns-map__card-photo--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ns-green);
}

.ns-map__card-photo--empty .ns-map__card-icon {
  opacity: 0.4;
}

.ns-map__card-photo--empty::after {
  display: none;
}

.ns-map__card-info {
  display: flex;
  flex: 1 0 auto;
  flex-direction: column;
  align-items: center;
  padding: 24px 20px;
  text-align: center;
}

.ns-map__card-name {
  margin-top: 0;
  color: var(--ns-beige-light);
  font-family: var(--font-heading);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-card-name);
  line-height: 1;
  letter-spacing: var(--tracking-heading);
}

.ns-map__card-role {
  margin-top: clamp(8px, 7.54px + 0.128vw, 10px);
  color: var(--ns-green-muted);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
}

.ns-map__card-divider {
  width: 100%;
  max-width: calc(100% - 40px);
  margin-top: clamp(9px, 6.92px + 0.577vw, 18px);
  border: none;
  border-top: 1px solid var(--ns-green-line);
}

.ns-map__card-links {
  display: flex;
  flex-direction: column;
  margin-top: clamp(19px, 16.46px + 0.705vw, 30px);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
}

.ns-map__card-links a {
  color: var(--ns-white);
  text-decoration: none;
}

.ns-map__card-links a:hover,
.ns-map__card-links a:focus-visible {
  text-decoration: underline;
}

@media (min-width: 1024px) {
  .ns-map__card-photo {
    aspect-ratio: 540 / 325;
    height: auto;
    /* Undo the base rule's <1024px cap — from 1024px the card's height is
       already reined in by ".ns-map__row"'s stretch-to-the-map's-height
       behaviour, so no separate photo cap is needed (or wanted: it broke
       the exact 325px checkpoint at 1920px). */
    max-height: none;
  }

  .ns-map__card-info {
    padding: clamp(24px, 23.31px + 0.192vw, 27px) 20px 32px;
  }
}

/* ---- Close button ---- */

.ns-map__card-close {
  position: absolute;
  top: 9px;
  right: 9px;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--close-btn-size);
  height: var(--close-btn-size);
  border-radius: 50%;
  background: var(--ns-beige-light);
  color: var(--ns-green);
  transition: background-color var(--dur-base) var(--ease-out);
}

.ns-map__card-close:hover,
.ns-map__card-close:focus-visible {
  background: var(--ns-beige-dark);
}

@media (min-width: 1024px) {
  .ns-map__card-close {
    top: 13px;
    right: 13px;
  }
}

/* ---- Social icons ---- */

.ns-footer__social-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--social-size);
  height: var(--social-size);
  border-radius: 50%;
  border: var(--social-ring) solid var(--ns-green);
  color: var(--ns-green);
  transition: color var(--dur-base) var(--ease-out);
}

.ns-footer__social-link svg {
  position: relative;
  z-index: 1;
}

/* Hover/focus fill, animated as a circle scaling in from the centre. */
.ns-footer__social-link::before {
  content: "";
  position: absolute;
  inset: calc(var(--social-ring) * -1);
  border-radius: 50%;
  background: var(--ns-green);
  transform: scale(0);
  transition: transform var(--dur-base) var(--ease-out);
}

.ns-footer__social-link:hover,
.ns-footer__social-link:focus-visible {
  color: var(--ns-beige-deep);
}

.ns-footer__social-link:hover::before,
.ns-footer__social-link:focus-visible::before {
  transform: scale(1);
}
