:root {
  /* Fonts */
  --font-heading: "Montserrat", system-ui, -apple-system, BlinkMacSystemFont,
    sans-serif;
  --font-body: "Nunito", system-ui, -apple-system, BlinkMacSystemFont,
    sans-serif;

  /* Colors */
  --color-bg-body: #fafafa;
  --color-bg-content: #ffffff;
  --color-text-primary: #333333;
  --color-text-heading: #444444;
  /* The site's blue. The primary buttons' darker hover and pressed shades are
     mixed from it below, so changing it here changes them too. CSS cannot
     reach the email templates, layout.html's theme-color meta or
     site.webmanifest: those carry #527c9f typed out. */
  --color-steel: #527c9f;
  --color-steel-hover: color-mix(in srgb, var(--color-steel), #000 15%);
  --color-steel-pressed: color-mix(in srgb, var(--color-steel), #000 23%);
  --color-steel-pressed-border: color-mix(in srgb, var(--color-steel), #000 29%);
  --color-nav-link: #cbd5db;
  --color-nav-link-hover: #ffffff;
  --color-link-hover: #428bca;
  --color-border: #dddddd;
  --color-border-light: #e3e3e3;

  /* Spacing */
  --spacing-xl: 5rem;

  /* Sizing */
  --article-img-size: 4rem; /* 64px converted to rem */
  --account-img-size: 7.813rem; /* 125px converted to rem */
}

/* Base Styles */
body {
  font-family: var(--font-body);
  background: var(--color-bg-body);
  color: var(--color-text-primary);
}

main {
  padding-top: var(--spacing-xl);
}

h1,
h2,
h3,
h4,
h5,
h6 {
  font-family: var(--font-heading);
  color: var(--color-text-heading);
}

.navbar-brand {
  font-family: var(--font-heading);
}

a {
  text-decoration: none;
}

a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--color-link-hover);
  outline-offset: 2px;
}

/* Headers and Navigation */
.bg-steel {
  background-color: var(--color-steel);
}

/* Dark mode: a deep shade of the same steel blue, so the bar belongs to the
   dark page instead of glaring over it, and a faint line to keep its edge. */
[data-bs-theme="dark"] .bg-steel {
  background-color: #22303c;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

/* The theme picker's drawn icons: text-sized, sitting on the text's baseline. */
.theme-icon {
  width: 1.1em;
  height: 1.1em;
  margin-right: 0.3em;
  vertical-align: -0.2em;
}

/* The sticky header floats once the page is scrolled: headerShadow.js adds
   .is-scrolled. Darker in dark mode, where a light shadow would not show. */
.site-header {
  transition: box-shadow 0.2s ease;
}

.site-header.is-scrolled {
  box-shadow: 0 6px 16px rgba(15, 23, 42, 0.3);
}

[data-bs-theme="dark"] .site-header.is-scrolled {
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.75);
}

/* Footer: the nav bar's colour (above), light text, white links. */
.site-footer {
  color: var(--color-nav-link);
}

.site-footer a {
  color: var(--color-nav-link-hover);
}

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

.site-footer-brand {
  font-family: var(--font-heading);
  font-size: 1.25rem;
  color: var(--color-nav-link-hover);
}

.site-footer-heading {
  font-weight: 600;
  color: var(--color-nav-link-hover);
}

.site-footer-rule {
  border-color: rgba(255, 255, 255, 0.25);
  opacity: 1;
}

/* In dark mode the faint edge line goes on top, where the footer meets the
   page, rather than underneath like the nav's. */
[data-bs-theme="dark"] .site-footer.bg-steel {
  border-bottom: 0;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.site-header .navbar-nav .nav-link {
  color: var(--color-nav-link);
  transition: color 0.2s ease-in-out;
}

/* :focus-visible, not :focus: a link clicked with the mouse keeps focus, and
   on the front page that left the clicked link white while ScrollSpy moved on,
   so it looked like the highlight was stuck. Keyboard users still see it. */
.site-header .navbar-nav .nav-link:hover,
.site-header .navbar-nav .nav-link:focus-visible {
  color: var(--color-nav-link-hover);
}

.site-header .navbar-nav .nav-link.active {
  font-weight: 600;
}

/* Content Sections */
.content-section {
  background: var(--color-bg-content);
  border: 1px solid var(--color-border);
  border-radius: 0.5rem;
  box-shadow: 0 2px 4px rgba(15, 23, 42, 0.05);
  transition: box-shadow 0.15s ease, transform 0.15s ease,
    border-color 0.15s ease;
}

.content-section:hover {
  box-shadow: 0 4px 10px rgba(15, 23, 42, 0.1);
  border-color: var(--color-border-light);
}

/* Sticky sidebar (md and up; below that the column stacks under the content).
   The sticky goes on the card, not on .col-md-4: Bootstrap's .row is a flex
   container, so the column already stretches to full height and would have no
   room to travel. */
@media (min-width: 768px) {
  .sidebar-sticky {
    position: sticky;
    top: 4.5rem; /* clears the fixed-top navbar */
  }
}

/* Articles */
.article-title {
  color: var(--color-text-heading);
  transition: color 0.2s ease-in-out;
}

a.article-title:hover,
a.article-title:focus {
  color: var(--color-link-hover);
  text-decoration: none;
}

.article-content {
  white-space: pre-line;
  font-size: 1.25rem;
}

.article-img {
  height: var(--article-img-size);
  width: var(--article-img-size);
  flex-shrink: 0;
  object-fit: cover;
  border: 1px solid var(--color-border-light);
  box-shadow: 0 0 0 2px var(--color-bg-content);
}

.article-metadata {
  padding-bottom: 0.063rem; /* 1px converted to rem */
  border-bottom: 1px solid var(--color-border-light);
}

.article-metadata a {
  transition: color 0.2s ease-in-out;
}

.article-metadata a:hover,
.article-metadata a:focus {
  color: var(--color-text-primary);
  text-decoration: none;
}

.article-svg {
  width: 1.563rem; /* 25px converted to rem */
  height: 1.563rem;
  vertical-align: middle;
}

/* Account/Profile */
.account-img {
  height: var(--account-img-size);
  width: var(--account-img-size);
  object-fit: cover;
}

.account-heading {
  font-size: 2.5rem;
}

.file-input-sm {
  max-width: 300px;
}

/* Stand-in for the native file input, whose button text the browser
   localizes. Values mirror Bootstrap's .form-control::file-selector-button
   so the control looks identical to the real thing. */
.file-input-label {
  display: flex;
  align-items: center;
  cursor: pointer;
  overflow: hidden;
}

.file-input-button {
  padding: 0.375rem 0.75rem;
  margin: -0.375rem -0.75rem;
  margin-inline-end: 0.75rem;
  color: var(--bs-body-color);
  background-color: var(--bs-tertiary-bg);
  border-color: inherit;
  border-style: solid;
  border-width: 0;
  border-inline-end-width: var(--bs-border-width);
  border-radius: 0;
  flex-shrink: 0;
}

.file-input-label:hover .file-input-button {
  background-color: var(--bs-secondary-bg);
}

.file-input-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#pictureInput:focus-visible + .file-input-label {
  border-color: #86b7fe;
  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
}

/* Custom Button Colors - Light Mode */
.btn-outline-primary {
  --bs-btn-color: var(--color-steel);
  --bs-btn-border-color: var(--color-steel);
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: var(--color-steel-hover);
  --bs-btn-hover-border-color: var(--color-steel-pressed);
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: var(--color-steel-pressed);
  --bs-btn-active-border-color: var(--color-steel-pressed-border);
}

.btn-outline-secondary {
  --bs-btn-color: #495057;
  --bs-btn-border-color: #6c757d;
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: #5a6268;
  --bs-btn-hover-border-color: #545b62;
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: #545b62;
  --bs-btn-active-border-color: #4e555b;
}

.btn-outline-danger {
  --bs-btn-color: #a85b5b;
  --bs-btn-border-color: #a85b5b;
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: #924e4e;
  --bs-btn-hover-border-color: #874848;
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: #874848;
  --bs-btn-active-border-color: #7c4242;
}

.btn-primary {
  --bs-btn-color: #fff;
  --bs-btn-bg: var(--color-steel);
  --bs-btn-border-color: var(--color-steel);
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: var(--color-steel-hover);
  --bs-btn-hover-border-color: var(--color-steel-pressed);
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: var(--color-steel-pressed);
  --bs-btn-active-border-color: var(--color-steel-pressed-border);
}

.btn-danger {
  --bs-btn-color: #fff;
  --bs-btn-bg: #a85b5b;
  --bs-btn-border-color: #a85b5b;
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: #924e4e;
  --bs-btn-hover-border-color: #874848;
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: #874848;
  --bs-btn-active-border-color: #7c4242;
}

/* Custom Button Colors - Dark Mode */
[data-bs-theme="dark"] .btn-outline-primary {
  --bs-btn-color: #8aadc8;
  --bs-btn-border-color: #8aadc8;
  --bs-btn-hover-color: #000;
  --bs-btn-hover-bg: #8aadc8;
  --bs-btn-hover-border-color: #9fbdd4;
  --bs-btn-active-color: #000;
  --bs-btn-active-bg: #9fbdd4;
  --bs-btn-active-border-color: #b4cde0;
}

[data-bs-theme="dark"] .btn-outline-secondary {
  --bs-btn-color: #b8bfc6;
  --bs-btn-border-color: #8a939b;
  --bs-btn-hover-color: #000;
  --bs-btn-hover-bg: #b8bfc6;
  --bs-btn-hover-border-color: #adb5bd;
  --bs-btn-active-color: #000;
  --bs-btn-active-bg: #adb5bd;
  --bs-btn-active-border-color: #a2aab2;
}

[data-bs-theme="dark"] .btn-outline-danger {
  --bs-btn-color: #d89090;
  --bs-btn-border-color: #d89090;
  --bs-btn-hover-color: #000;
  --bs-btn-hover-bg: #d89090;
  --bs-btn-hover-border-color: #e0a8a8;
  --bs-btn-active-color: #000;
  --bs-btn-active-bg: #e0a8a8;
  --bs-btn-active-border-color: #e8bcbc;
}

/* Responsive Adjustments */
@media (max-width: 768px) {
  .account-heading {
    font-size: 2rem;
  }

  .article-img {
    height: 3rem;
    width: 3rem;
  }
}

/* Dark Mode Features */

[data-bs-theme="dark"] {
  --color-bg-body: #1a1a1a;
  --color-bg-content: #2d2d2d;
  --color-text-primary: #e0e0e0;
  --color-text-heading: #f0f0f0;
  --color-border: #404040;
  --color-border-light: #4a4a4a;
}

[data-bs-theme="dark"] .content-section {
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}

[data-bs-theme="dark"] article.content-section:hover {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
}

/* Custom Modal Colors */
.modal-header.bg-success {
  background-color: #4a7c5d !important;
}

.modal-header.bg-danger {
  background-color: #a85b5b !important;
}

/* Ensure modal header text stays white in both themes */
.modal-header.bg-success .modal-title,
.modal-header.bg-danger .modal-title {
  color: #ffffff !important;
}

/* ---------- Front page ---------- */

/* The front page's nav is sticky, not fixed, so main needs no clearance. */
main.front {
  padding-top: 0;
}

.front-section {
  padding: 3.5rem 0;
}

.front-hero {
  padding: 5rem 0 4rem;
}

/* Outside a collapsed menu, Bootstrap makes navbar dropdowns static below lg,
   which would push the page down instead of opening over it. */
.front-theme .dropdown-menu {
  position: absolute;
}

/* Every other section on a tinted band, so the page reads in blocks. */
.front-section:nth-of-type(even) {
  background: var(--bs-tertiary-bg);
}

/* In light mode Bootstrap's tertiary grey (#f8f9fa) is almost the page's own
   #fafafa, so the bands vanished. A faint tint of the site's steel blue
   instead; dark mode keeps the grey, which already stands out there. */
[data-bs-theme="light"] .front-section:nth-of-type(even) {
  background: #eef3f7;
}

/* The silhouettes beside Enskilt and Grupp, in the site's blue; a lighter
   blue in dark mode, where the steel would sink into the dark card. */
/* In each offer card's top right corner, about as tall as the heading and
   the price together. */
.offer-icon {
  height: 4.5rem;
  width: auto;
  flex-shrink: 0;
  color: var(--color-steel);
}

/* The front person in the group icon: a stroke in the card's own colour,
   drawn under the fill, leaves a thin gap where it overlaps the two behind -
   the same gap as between each head and its shoulders. */
.offer-icon-front {
  stroke: var(--bs-card-bg, var(--bs-body-bg));
  stroke-width: 1.4;
  paint-order: stroke fill;
}

[data-bs-theme="dark"] .offer-icon {
  color: #8aadc8;
}

/* The offer cards and the testimonial cards lift toward the pointer. The
   whole offer card is a link (stretched-link on its button), and the lift
   says so. Hover only with a
   real pointer: a phone has no hover. Keyboard focus gets the same lift,
   through :focus-visible, not :focus-within - a clicked card keeps focus and
   would stay lifted, the stuck highlight the nav had. With reduced motion
   the card gains the shadow but does not move. In dark mode a shadow hardly
   shows, so the border lightens as well. */
.offer-card,
.testimonial-card {
  --offer-lift-shadow: 0 10px 24px rgba(15, 23, 42, 0.18);
  --offer-lift-border: var(--bs-border-color);
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}

[data-bs-theme="dark"] .offer-card,
[data-bs-theme="dark"] .testimonial-card {
  --offer-lift-shadow: 0 10px 24px rgba(0, 0, 0, 0.6);
  --offer-lift-border: rgba(255, 255, 255, 0.35);
}

.offer-card:has(:focus-visible) {
  box-shadow: var(--offer-lift-shadow);
  border-color: var(--offer-lift-border);
}

@media (hover: hover) {
  .offer-card:hover,
  .testimonial-card:hover {
    box-shadow: var(--offer-lift-shadow);
    border-color: var(--offer-lift-border);
  }
}

@media (prefers-reduced-motion: no-preference) {
  .offer-card:has(:focus-visible) {
    transform: translateY(-4px);
  }
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .offer-card:hover,
  .testimonial-card:hover {
    transform: translateY(-4px);
  }
}

/* A tight line height: where the group icon leaves the price too little
   room, "i timmen" (kept whole by text-nowrap) wraps just below the amount,
   not a 2rem line further down. */
.front-price {
  font-size: 2rem;
  font-weight: 700;
  line-height: 1.2;
}

/* The proof strip as a slideshow (two or more featured quotes): one quote
   at a time, centred and a little larger, the dots centred below. */
.proof-carousel .carousel-item,
.proof-single {
  text-align: center;
}

.front-proof .proof-quote {
  max-width: 44rem;
  margin: 0 auto 0.75rem;
  font-size: 1.35rem;
}

/* Bootstrap draws the dots as white bars over a photo; here they are small
   dots in the site's blue under the text, lighter in dark mode. */
.proof-carousel .proof-dots {
  position: static;
  margin: 1.25rem 0 0;
  gap: 0.5rem;
}

.proof-carousel .proof-dots [data-bs-target] {
  width: 0.625rem;
  height: 0.625rem;
  margin: 0;
  border: 0;
  border-radius: 50%;
  background-color: var(--color-steel);
  opacity: 0.35;
}

.proof-carousel .proof-dots .active {
  opacity: 1;
}

[data-bs-theme="dark"] .proof-carousel .proof-dots [data-bs-target] {
  background-color: #8aadc8;
}

.front-step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  margin-right: 0.5rem;
  border-radius: 50%;
  background: var(--color-steel);
  color: #ffffff;
}

/* Henrik's photo in Om mig: 200px on a phone, 280px from md up, from a
   600x600 file so it stays sharp on high-density screens. */
.about-photo {
  width: 200px;
  height: 200px;
  object-fit: cover;
}

@media (min-width: 768px) {
  .about-photo {
    width: 280px;
    height: 280px;
  }
}

.testimonial-photo {
  object-fit: cover;
}

/* Omdömen: one row of equal cards that scrolls sideways and snaps to a card.
   flex-basis is 85% on a phone so the next card peeks in, and stops growing
   at 22rem so a computer shows about three. Cards stretch to the tallest
   (the flex row's default), and the signature sits at the bottom
   (mt-auto in the template). min-width: 0 lets the row shrink inside its
   flex wrapper instead of stretching the page. The vertical padding leaves
   room for a lifted card's shadow, which overflow would otherwise clip; the
   side padding only keeps the cards off the edge (a shadow may clip at the
   row's ends), and scroll-padding-inline keeps the snapped card at that
   inset. The scrollbar is hidden like the nav's: the fade (set by the
   script) shows there is more, and a mouse has the arrows. The focus ring
   is drawn on the wrapper, because the fade's mask would dissolve one drawn
   on the row. */
.testimonial-wrap {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.testimonial-row {
  display: flex;
  flex: 1 1 auto;
  gap: 1.5rem;
  min-width: 0;
  padding: 1.25rem 0.5rem 2rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: 0.5rem;
  scrollbar-width: none;
}

.testimonial-row:focus-visible {
  outline: none;
}

.testimonial-wrap:has(.testimonial-row:focus-visible) {
  outline: 2px solid var(--color-link-hover);
  outline-offset: 2px;
}

.testimonial-row::-webkit-scrollbar {
  display: none;
}

.testimonial-card {
  flex: 0 0 min(85%, 22rem);
  scroll-snap-align: start;
}

/* Arrow buttons: for a mouse only, and only while the row overflows
   (testimonialRow.js puts .is-scrollable on the wrapper). At the end of the
   row an arrow greys out but stays focusable (aria-disabled, not disabled),
   so a keyboard user's focus is not dropped. */
.testimonial-arrow {
  display: none;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  border: 1px solid var(--bs-border-color);
  border-radius: 50%;
  background: var(--bs-body-bg);
  color: var(--bs-body-color);
}

@media (hover: hover) and (pointer: fine) {
  .testimonial-wrap.is-scrollable .testimonial-arrow {
    display: inline-flex;
  }
}

.testimonial-arrow:hover:not([aria-disabled="true"]) {
  background: var(--bs-secondary-bg);
}

.testimonial-arrow[aria-disabled="true"] {
  opacity: 0.35;
  cursor: default;
}

.faq-item summary {
  cursor: pointer;
  font-weight: 600;
}

/* A blank line in an answer in faq.toml becomes a paragraph break. */
.faq-answer {
  white-space: pre-line;
}

/* Intresserad av: one per line on a phone, where three in a row wrapped as
   one and two; one row from sm up, as form-check-inline. */
@media (min-width: 576px) {
  .interest-option {
    display: inline-block;
    margin-right: 1rem;
  }
}

/* Hur hittade du hit?: one per line on a phone, then columns, each as wide
   as its longest choice, so the second row lines up under the first (words
   wrapping freely left Annat out of line). Two columns from sm, three from
   md, where they fit. */
@media (min-width: 576px) {
  .source-choices {
    display: grid;
    grid-template-columns: repeat(2, max-content);
    column-gap: 1.5rem;
  }
}

@media (min-width: 768px) {
  .source-choices {
    grid-template-columns: repeat(3, max-content);
  }
}

/* The contact form's trap field: off screen rather than display:none, which
   some bots recognise and skip. */
.contact-trap {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Smooth anchor jumps, done by the browser so they honour scroll-margin-top
   below. Not for visitors who asked their system for less motion. */
@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

/* Anchor jumps land exactly below the sticky nav: 6rem below lg, where it is
   two rows (brand, then the section links), 3.5rem (56px) from lg up. More
   than the nav's height leaves a strip of the section above showing. */
.front-section {
  scroll-margin-top: 6rem;
}

/* The last section nearly fills the screen below the nav: scrolled to the
   end, the page shows Kontakt with the top of the footer (4rem) peeking up,
   never the end of Frågor above it. The full screen left a large empty band
   under the form on big screens. */
#kontakt {
  min-height: calc(100vh - 3.5rem - 4rem);
}

.front-nav {
  width: 100%;
  scrollbar-width: none;
}

.front-nav .nav-link {
  white-space: nowrap;
}

/* A narrow screen's link row, and the Omdömen row, fade out at an edge while
   there is more to swipe to on that side; navFollow.js and testimonialRow.js
   set the classes. A fade of 0 is a hard stop at the edge, so one gradient
   serves either side or both. */
.front-nav,
.testimonial-row {
  --fade-left: 0px;
  --fade-right: 0px;
}

.front-nav.has-more-left,
.testimonial-row.has-more-left {
  --fade-left: 2.5rem;
}

.front-nav.has-more-right,
.testimonial-row.has-more-right {
  --fade-right: 2.5rem;
}

.front-nav.has-more-left,
.front-nav.has-more-right,
.testimonial-row.has-more-left,
.testimonial-row.has-more-right {
  -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--fade-left),
    #000 calc(100% - var(--fade-right)), transparent);
  mask-image: linear-gradient(to right, transparent, #000 var(--fade-left),
    #000 calc(100% - var(--fade-right)), transparent);
}

/* The section in view, set by ScrollSpy: white and underlined. Bold alone was
   too faint to see move. */
.front-nav .nav-link.active {
  color: var(--color-nav-link-hover);
  box-shadow: inset 0 -2px 0 currentColor;
}

/* lg, where the front nav becomes one row (navbar-expand-lg in nav.html). */
@media (min-width: 992px) {
  .front-section {
    scroll-margin-top: 3.5rem;
  }

  .front-nav {
    width: auto;
  }
}
