/* =========================================================================
   features.css — additive layer, loaded after styles.css
   Two things live here and nothing else:
     1. .calc      — the payback plate in "Räkna på det"
     2. .demo      — the five show-don't-tell device mock-ups in the offer list
   Everything is built from the tokens in styles.css. No new colours, no new
   type scale, no overrides of existing rules.
   ========================================================================= */

/* =========================================================================
   SUBORDINATE PHONE LINK
   The booking .btn stays the single primary CTA. This is deliberately not a
   button: it is the same underlined .link treatment used elsewhere, sat
   under the CTA so it never competes for the same glance.
   ========================================================================= */
/* The whole line is the link, with a 44px minimum box — as an inline <a> this
   was a 16px-tall target, on a page read one-handed in a van. */
.cta-phone {
  margin-top: var(--s1);
  min-height: 44px;
  padding: 0.5rem 0.75rem;
  font-size: var(--step--1);
  color: var(--dimma);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  text-decoration: none;
  border-radius: var(--radius);
}
.cta-phone:hover { background: color-mix(in srgb, var(--gran) 4%, transparent); }
.cta-phone__num {
  color: var(--gran);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: var(--ockra);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
.cta-phone svg {
  width: 0.95em;
  height: 0.95em;
  stroke: var(--ockra);
  fill: none;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}
/* In the header the number sits beside the wordmark, ahead of the CTA. */
.header-phone {
  margin-inline-start: auto;
  margin-inline-end: var(--s3);
  min-height: 44px;
  padding-inline: 0.35rem;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: var(--step--1);
  font-weight: 600;
  white-space: nowrap;
}
.header-phone svg {
  width: 1em;
  height: 1em;
  stroke: var(--ockra);
  fill: none;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}
/* 560–699px: the number is dropped, the tappable icon stays. */
@media (max-width: 699px) {
  .header-phone { margin-inline-end: var(--s2); }
  .header-phone .header-phone__num { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .header-phone svg { width: 1.25rem; height: 1.25rem; }
}
/* Below 560px there is genuinely no room: the wordmark plus a booking CTA that
   already wraps to two lines fills the bar. The number is still one thumb away
   in the hero and in Kontakt. */
@media (max-width: 559px) {
  .header-phone { display: none; }
}

/* =========================================================================
   RÄKNA PÅ DET — payback plate
   The plate only ever holds concrete, checkable facts (see styles.css), and
   this is arithmetic on our own published price, so it qualifies.
   ========================================================================= */
/* One width for both additions, so the payback plate and the offer cards below
   it always line up. Change it here and both follow. */
/* 52rem, not 66: at 66 the copy filled barely two-thirds of its column, so the
   leftover width piled up between the text and the device. Swept 50–66rem — at
   52 the gap spread across the five cards drops from 120px to 53px while the
   text still sits on one comfortable measure. */
:root {
  --feature-measure: 66rem;   /* the card's outer width */
  --demo-content: 46rem;      /* the width the text + device actually occupy */
}

/* Capped and centred — the 1440px container is far too wide for a two-column
   readout, and this keeps the plate flush with the cards underneath. */
.calc { margin-top: var(--s5); margin-inline: auto; max-width: var(--feature-measure); text-align: left; }
.calc__grid { display: grid; gap: var(--s4); }
/* Two columns only from 768px. At 700 the column is so narrow that the readout
   sentence needs a fourth line, which would mean reserving dead space at every
   width above it. */
@media (min-width: 768px) {
  .calc__grid { grid-template-columns: 1fr 1fr; gap: var(--s5); align-items: center; }
}
.calc__label {
  display: block;
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--dimma);
  margin-bottom: 0.35rem;
}
.calc__figure {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.7rem, 1.3rem + 1.6vw, 2.3rem);
  letter-spacing: -0.02em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.calc__slider {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 6px;
  margin: var(--s3) 0 0.4rem;
  border-radius: 999px;
  background: linear-gradient(to right, var(--ockra) var(--pct, 20%), var(--border) var(--pct, 20%));
  cursor: pointer;
}
.calc__slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--ockra);
  border: 3px solid var(--papper);
  box-shadow: 0 1px 4px rgba(28, 43, 38, 0.3);
  cursor: grab;
}
.calc__slider::-moz-range-thumb {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--ockra);
  border: 3px solid var(--papper);
  box-shadow: 0 1px 4px rgba(28, 43, 38, 0.3);
  cursor: grab;
}
.calc__ends {
  display: flex;
  justify-content: space-between;
  font-size: var(--step--1);
  color: var(--dimma);
  font-variant-numeric: tabular-nums;
}
.calc__out { border-left: 2px solid var(--ockra); padding-left: var(--s3); }
.calc__count {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2.1rem, 1.5rem + 2.6vw, 3rem);
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
/* Target the unit by class, not `.calc__count span` — that also caught the
   number itself and shrank the answer to the size of its own label. */
.calc__count-unit {
  font-family: var(--font-body);
  font-size: 0.42em;
  font-weight: 600;
  color: var(--gran);
  letter-spacing: 0;
}
/* The cadence phrase changes length as the slider moves ("ett jobb om året"
   vs "ungefär ett jobb varannan vecka"), which re-wraps this sentence and
   would resize the whole plate under the reader's thumb. Reserve the tallest
   line count up front so the plate never moves. 1.65 is the body line-height. */
.calc__say {
  margin-top: var(--s2);
  color: var(--dimma);
  max-width: 34ch;
  min-height: calc(5 * 1.65em); /* 320px: the longest phrase runs to five lines */
}
@media (min-width: 360px) {
  .calc__say { min-height: calc(4 * 1.65em); }
}
@media (min-width: 390px) {
  /* Everything from here up fits the longest phrase in three lines. */
  .calc__say { min-height: calc(3 * 1.65em); }
}
.calc__say strong { color: var(--gran); font-weight: 700; }
.calc__foot {
  margin-top: var(--s3);
  padding-top: var(--s2);
  border-top: 1px solid var(--border);
  font-size: var(--step--1);
  color: var(--dimma);
  max-width: none;
  font-variant-numeric: tabular-nums;
}

/* =========================================================================
   OFFER LIST — demo variant
   Keeps .offer-card so the existing reveal stagger in styles.css still
   applies. Only the internal layout changes: one card per row, text and
   device side by side, alternating which side the device sits on.
   ========================================================================= */
.offer-list--demo {
  /* Device palette, derived from the brand ink so nothing new enters the system. */
  --demo-shell: #17241f;
  --demo-screen: #101a16;
  --demo-line: rgba(238, 240, 234, 0.12);
  --demo-panel: #1e2c26;

  grid-template-columns: 1fr; /* override the 2-col rule from styles.css */
  text-align: left;
  /* One card per row across a 1440px container is too wide to read; cap it.
     Shares --feature-measure with the payback plate above. */
  max-width: var(--feature-measure);
  margin-inline: auto;
}
@media (min-width: 700px) {
  /* The full-width 5th-card exception in styles.css does not apply here —
     every card is already full width. */
  .offer-list--demo { grid-template-columns: 1fr; }
  .offer-list--demo .offer-card:nth-child(5) { grid-column: auto; text-align: left; }
  .offer-list--demo .offer-card:nth-child(5) .offer-card__head { justify-content: flex-start; }
  .offer-list--demo .offer-card:nth-child(5) .offer-card__icon svg { margin-inline: 0; }
  .offer-list--demo .offer-card:nth-child(5) .offer-card__points { grid-template-columns: 1fr; column-gap: 0; }
  .offer-list--demo .offer-card:nth-child(5) .offer-card__points li { padding-left: 1.4rem; max-width: 52ch; }
  .offer-list--demo .offer-card:nth-child(5) .offer-card__points li::before {
    position: absolute;
    display: block;
    margin-right: 0;
  }
}
/* Centred, not start-aligned: the device column is always ~200px taller than
   the text beside it, and top-aligning pools all of that slack into one hole
   under the copy. Split evenly it reads as breathing room instead. */
.offer-card--demo { display: grid; gap: var(--s4); align-items: center; }
@media (min-width: 900px) {
  /* `auto` rather than 1fr: the device column shrinks to the device instead of
     taking half the card, so the phone sits beside the text rather than
     floating in the middle of its own empty half. Tops align because the two
     columns are never the same height. */
  .offer-card--demo { grid-template-columns: 1fr auto; gap: var(--s5); }
  /* Alternate the device side so the eye zig-zags down the list. The template
     flips with it, otherwise the device would land back in the 1fr column. */
  .offer-card--demo:nth-child(even) { grid-template-columns: auto 1fr; }
  .offer-card--demo:nth-child(even) .offer-card__demo { order: -1; }

  /* The copy is capped well below the width of its column, so ~220px of slack
     is always left over. Pin the copy to the card's outer edge and that slack
     lands in the middle gap on every row — instead of in the middle on the
     odd cards and out at the right edge on the even ones. */
  /* No explicit width. justify-self takes the block out of stretch, so it
     shrinks to exactly its own longest line — a fixed 52ch left 110–130px of
     ragged space inside the block, which hid beside the device on the odd
     cards but showed as a wide right margin on the even ones. */
  .offer-card__text { justify-self: start; max-width: 100%; }
  .offer-card--demo:nth-child(even) .offer-card__text { justify-self: end; }

  /* The card keeps its full width; everything beyond --demo-content becomes
     padding, so the text and device stay exactly where they are and the extra
     width reads as breathing room rather than spreading the layout apart. */
  .offer-card--demo {
    padding-block: var(--s5);
    padding-inline: max(var(--s5), calc((100% - var(--demo-content)) / 2));
  }
}
@media (max-width: 699px) {
  /* Give the device room on narrow phones. */
  .offer-card--demo { padding: var(--s3); }
}
.offer-card__demo { display: flex; justify-content: center; }
/* A definite width. `min(244px, 100%)` on the device resolved its 100% against
   an auto-sized grid column, which is circular — the device collapsed to 55px
   and every line inside it wrapped. */
/* Fluid below the two-column breakpoint — a fixed width here sets a hard
   min-content floor that pushed the whole card past a 320px viewport. From
   900px up the column is `auto`, so the width must be definite instead. */
.demo { margin: 0; width: 100%; max-width: var(--demo-w, 244px); }

.offer-card__demo { min-width: 0; }
@media (min-width: 900px) {
  .demo { width: var(--demo-w, 244px); }
}
/* The old caption sat centred under the device while the copy beside it was
   left-aligned — two alignment systems in one card. It now closes the text
   column instead, which also shortens the card by ~60px. */
.offer-card__note {
  margin-top: var(--s3);
  padding-top: var(--s2);
  border-top: 1px solid var(--line-soft, var(--border));
  font-size: var(--step--1);
  color: var(--dimma);
  max-width: 46ch;
}
/* ---- the device shell ---- */
.phone {
  /* One height for every device in the section, browser panel included, so the
     five cards form a rhythm instead of each sizing to its own content. */
  height: var(--demo-h, 430px);
  width: 100%;
  background: var(--demo-shell);
  border-radius: 28px;
  padding: 9px;
  box-shadow:
    0 2px 4px rgba(28, 43, 38, 0.12),
    0 18px 40px rgba(28, 43, 38, 0.22);
}
.phone__screen {
  background: var(--demo-screen);
  border-radius: 20px;
  overflow: hidden;
  height: 100%;
  display: flex;
  flex-direction: column;
  color: var(--on-dark);
  font-size: 12.5px;
  line-height: 1.45;
}
.phone__status {
  display: flex;
  justify-content: space-between;
  padding: 9px 14px 2px;
  font-size: 10px;
  font-weight: 600;
  color: var(--on-dark-dim);
  flex: none;
  font-variant-numeric: tabular-nums;
}
.phone__stage { flex: 1; position: relative; overflow: hidden; }
.phone__view {
  position: absolute;
  inset: 0;
  padding: 12px;
  display: flex;
  flex-direction: column;
  opacity: 0;
  transition: opacity 400ms ease;
}
.phone__view.is-on { opacity: 1; }

/* A step of a sequence: hidden until its turn, then faded in. */
.stepin { opacity: 0; transform: translateY(6px); transition: opacity 400ms ease, transform 400ms ease; }
.stepin.is-on { opacity: 1; transform: none; }

/* ---- message bubbles (demos 2 and 3) ---- */
.msg-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-bottom: 9px;
  border-bottom: 1px solid var(--demo-line);
  margin-bottom: 10px;
  flex: none;
}
.msg-head__who { font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; }
.msg-head__sub { font-size: 10px; color: var(--on-dark-dim); }
.msg-body { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; overflow: hidden; }
.bubble {
  max-width: 86%;
  padding: 8px 11px;
  border-radius: 14px;
  font-size: 12px;
  line-height: 1.4;
  margin-bottom: 7px;
}
.bubble--out { background: var(--ockra); color: #fff; border-bottom-right-radius: 4px; margin-left: auto; }
.bubble--in { background: var(--demo-panel); color: var(--on-dark); border-bottom-left-radius: 4px; }
.bubble__time { display: block; font-size: 9.5px; opacity: 0.75; margin-top: 4px; font-variant-numeric: tabular-nums; }
.auto-flag {
  align-self: flex-end;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ockra);
  margin: -2px 2px 9px auto;
}
.auto-flag svg { width: 10px; height: 10px; fill: currentColor; }
.avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--demo-panel);
  display: grid;
  place-items: center;
  flex: none;
}
.avatar svg { width: 14px; height: 14px; stroke: var(--on-dark-dim); fill: none; stroke-width: 1.7; }

/* ---- demo 1: a real-looking mobile site behind a pinned call bar ---- */
.mini { background: var(--papper); color: var(--gran); }
.mini__nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 11px 13px;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.09em;
  background: #fff;
  border-bottom: 1px solid var(--border);
}
.mini__burger { width: 13px; height: 9px; border-top: 1.5px solid var(--gran); border-bottom: 1.5px solid var(--gran); position: relative; }
.mini__burger::after { content: ""; position: absolute; left: 0; right: 0; top: 3px; border-top: 1.5px solid var(--gran); }

/* Hero: a real photograph with the copy laid over it, as on the built sites. */
.mini__hero { position: relative; isolation: isolate; }
.mini__heroimg { width: 100%; height: 150px; object-fit: cover; display: block; }
.mini__hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(16, 26, 22, 0.12) 0%, rgba(16, 26, 22, 0.42) 42%, rgba(16, 26, 22, 0.9) 100%);
}
.mini__herotext { position: absolute; inset: auto 0 0 0; z-index: 1; padding: 0 13px 12px; color: #fff; }
.mini__eyebrow { font-size: 8px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: #d9a86a; }
.mini__h {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 16px;
  line-height: 1.12;
  margin-top: 4px;
}
.mini__s { font-size: 9.5px; opacity: 0.85; margin-top: 4px; }
.mini__btns { display: flex; gap: 5px; margin-top: 9px; }
.mini__btns span {
  font-size: 9px;
  font-weight: 700;
  padding: 6px 10px;
  border-radius: 5px;
  border: 1px solid rgba(255, 255, 255, 0.45);
}
.mini__btns .is-primary { background: var(--ockra); border-color: var(--ockra); }

.mini__body { padding: 13px; }
.mini__lbl { font-size: 8.5px; font-weight: 700; letter-spacing: 0.11em; text-transform: uppercase; color: var(--dimma); margin: 0 0 8px; }
.mini__lbl + * { margin-bottom: 14px; }
.mini__tiles { display: grid; gap: 7px; }
.mini__tile {
  display: flex;
  align-items: center;
  gap: 8px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 7px;
  padding: 7px 9px;
}
.mini__tile i { width: 22px; height: 22px; border-radius: 6px; background: #ece5db; display: grid; place-items: center; flex: none; }
.mini__tile svg { width: 12px; height: 12px; stroke: var(--ockra); fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.mini__tile b { font-size: 10.5px; display: block; line-height: 1.2; }
.mini__tile span { font-size: 9px; color: var(--dimma); }
.mini__copy { font-size: 9.5px; line-height: 1.55; color: var(--dimma); max-width: none; }
.mini__areas { display: flex; flex-wrap: wrap; gap: 4px; max-width: none; }
.mini__areas span {
  font-size: 8.5px;
  font-weight: 600;
  color: var(--gran);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px 8px;
}
.mini__contact { display: grid; gap: 6px; }
.mini__contact p { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; background: #fff; border: 1px solid var(--border); border-radius: 6px; padding: 7px 9px; max-width: none; }
.mini__contact b { font-size: 10px; }
.mini__contact span { font-size: 8.5px; color: var(--dimma); }
.mini__foot { margin-top: 14px; padding-top: 10px; border-top: 1px solid var(--border); font-size: 8px; color: var(--faint, var(--dimma)); max-width: none; }

/* min-height:0 lets the page scroll inside without shoving the bar off-screen. */
.mini__viewport { flex: 1; min-height: 0; overflow: hidden; position: relative; }
.mini__page { position: absolute; inset: 0 0 auto 0; transition: transform 2600ms cubic-bezier(0.4, 0, 0.2, 1); }
.mini__callbar {
  flex: none;
  background: var(--ockra);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 11px;
  font-size: 12px;
  font-weight: 700;
  position: relative;
  overflow: hidden;
  font-variant-numeric: tabular-nums;
}
.mini__callbar svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 2.2; stroke-linecap: round; }
.mini__ripple {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.5);
  transform: translate(-50%, -50%) scale(0);
  opacity: 0;
  pointer-events: none;
}
.is-tapped .mini__ripple { animation: demo-tap 1s ease-out; }
@keyframes demo-tap {
  from { transform: translate(-50%, -50%) scale(0); opacity: 0.7; }
  to { transform: translate(-50%, -50%) scale(15); opacity: 0; }
}

/* ---- demo 3: the incoming-call screen ---- */
.call { align-items: center; justify-content: center; text-align: center; }
.call__avatar {
  width: 68px;
  height: 68px;
  border-radius: 50%;
  background: var(--demo-panel);
  display: grid;
  place-items: center;
  margin-bottom: 11px;
}
.call__avatar svg { width: 27px; height: 27px; stroke: var(--on-dark-dim); fill: none; stroke-width: 1.7; }
.call__num { font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums; }
.call__status { font-size: 11.5px; color: var(--on-dark-dim); margin-top: 3px; }
.call__status.is-missed { color: #d0705f; font-weight: 700; }
.call__actions { display: flex; gap: 28px; margin-top: 28px; transition: opacity 400ms ease; }
.call__btn { width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center; }
.call__btn svg { width: 18px; height: 18px; stroke: #fff; fill: none; stroke-width: 2.3; stroke-linecap: round; }
.call__btn--decline { background: #a53d2e; }
.call__btn--answer { background: #2c6b41; }
@media (prefers-reduced-motion: no-preference) {
  .call__avatar { animation: call-ring 1.7s ease-out infinite; }
  @keyframes call-ring {
    from { box-shadow: 0 0 0 0 rgba(178, 106, 40, 0.45); }
    70% { box-shadow: 0 0 0 20px rgba(178, 106, 40, 0); }
    to { box-shadow: 0 0 0 0 rgba(178, 106, 40, 0); }
  }
  /* Once the call has been missed the ring stops. */
  .call__status.is-missed ~ .call__actions,
  .call:has(.is-missed) .call__avatar { animation: none; }
}

/* ---- demo 2: the review request, ending on the one-tap rating sheet ---- */
.job-flag {
  align-self: center;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--on-dark-dim);
  background: rgba(238, 240, 234, 0.07);
  border-radius: 999px;
  padding: 4px 10px;
  margin-bottom: 9px;
  flex: none;
}
.rate-sheet {
  background: #fff;
  color: var(--gran);
  border-radius: 11px;
  padding: 12px;
  text-align: center;
}
.rate-sheet__who { font-size: 11px; font-weight: 700; }
.rate-sheet__ask { font-size: 9.5px; color: var(--dimma); margin-top: 2px; }
.rate-sheet__stars { display: flex; justify-content: center; gap: 4px; margin-top: 9px; }
.rate-sheet__stars svg { width: 19px; height: 19px; }
.rate-sheet__stars svg path { fill: #d8dad2; transition: fill 220ms ease; }
.rate-sheet__stars .is-lit path { fill: var(--ockra); }
.rate-sheet__foot {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: 0.07em;
  color: var(--dimma);
  margin-top: 10px;
}
.rate-sheet__foot svg { width: 10px; height: 10px; stroke: var(--dimma); fill: none; stroke-width: 2; }

/* ---- demo 4: the Google profile, fields filled ---- */
.gsearch {
  display: flex;
  align-items: center;
  gap: 8px;
  background: #fff;
  border-radius: 999px;
  padding: 8px 12px;
  flex: none;
  margin-bottom: 10px;
}
.gsearch svg { width: 13px; height: 13px; stroke: var(--dimma); fill: none; stroke-width: 2.2; flex: none; }
.gsearch__q { font-size: 11.5px; color: var(--gran); }
.gsearch__caret { display: inline-block; width: 1.5px; height: 12px; background: var(--gran); vertical-align: -2px; }
.gcard { background: #fff; color: var(--gran); border-radius: 11px; padding: 11px; }
.gcard__name { font-size: 12.5px; font-weight: 700; }
.gcard__meta { font-size: 10px; color: var(--dimma); margin-top: 3px; }
.gcard__open { color: #2c6b41; font-weight: 700; }
.gcard__shots { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; margin-top: 9px; }
.gcard__shots span { display: block; aspect-ratio: 4 / 3; border-radius: 5px; background: var(--border); }
.gcard__btns { display: flex; gap: 5px; margin-top: 9px; }
.gcard__btns span { font-size: 9.5px; font-weight: 700; padding: 5px 9px; border-radius: 999px; border: 1px solid var(--border); }
.gcard__btns .is-primary { background: var(--ockra); color: #fff; border-color: var(--ockra); }
.gticks__label {
  margin-top: auto;
  padding-top: 12px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--on-dark-dim);
  max-width: none;
}
.gticks { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 7px; }
.gtick {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 9px;
  font-weight: 700;
  color: var(--on-dark-dim);
  background: rgba(238, 240, 234, 0.07);
  border-radius: 999px;
  padding: 4px 8px;
  white-space: nowrap;
}
.gtick svg { width: 9px; height: 9px; stroke: var(--ockra); fill: none; stroke-width: 3.4; stroke-linecap: round; stroke-linejoin: round; }

/* ---- demo 5: the running-site panel (a browser, not a phone) ---- */
.panel {
  width: 100%;
  background: var(--papper);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow:
    0 2px 4px rgba(28, 43, 38, 0.1),
    0 18px 40px rgba(28, 43, 38, 0.16);
}
.panel__bar { display: flex; align-items: center; gap: 7px; padding: 9px 11px; background: var(--kalk); border-bottom: 1px solid var(--border); }
.panel__dots { display: flex; gap: 4px; flex: none; }
.panel__dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--border); display: block; }
.panel__url {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 5px;
  background: var(--papper);
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 11px;
  font-weight: 600;
}
.panel__url svg { width: 11px; height: 11px; stroke: #2c6b41; fill: none; stroke-width: 2.2; flex: none; }
.panel__body { padding: 15px; }
.panel__mail {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 11px;
  background: var(--kalk);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 12px;
}
.panel__mail i { width: 27px; height: 27px; border-radius: 6px; background: #ece5db; display: grid; place-items: center; flex: none; }
.panel__mail svg { width: 14px; height: 14px; stroke: var(--ockra); fill: none; stroke-width: 1.8; }
.panel__mail b { display: block; font-size: 11.5px; }
.panel__mail span { font-size: 9.5px; color: var(--dimma); }
.panel__lbl { font-size: 9px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; color: var(--dimma); margin-bottom: 7px; }
.panel__row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 0;
  border-bottom: 1px solid var(--border);
  font-size: 11.5px;
}
.panel__row:last-child { border-bottom: none; }
.panel__ok { width: 15px; height: 15px; border-radius: 50%; background: #2c6b41; display: grid; place-items: center; flex: none; }
.panel__ok svg { width: 8px; height: 8px; stroke: #fff; fill: none; stroke-width: 4; stroke-linecap: round; stroke-linejoin: round; }
.panel__name { flex: 1; }
.panel__val { font-size: 10.5px; color: var(--dimma); }
.panel__pulse { width: 6px; height: 6px; border-radius: 50%; background: #2c6b41; flex: none; position: relative; }
.panel__pulse::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: #2c6b41; }

@media (prefers-reduced-motion: no-preference) {
  .panel__pulse::after { animation: panel-pulse 2.2s ease-out infinite; }
  @keyframes panel-pulse {
    from { transform: scale(1); opacity: 0.55; }
    to { transform: scale(3.2); opacity: 0; }
  }
  .gsearch__caret { animation: caret-blink 1s steps(1) infinite; }
  @keyframes caret-blink { 50% { opacity: 0; } }
}

/* =========================================================================
   MOBILE — the card stacks, so it centres
   Mirrors the treatment styles.css already gives its centred fifth card,
   including moving the bullet dash inline so it sits with the text.
   ========================================================================= */
@media (max-width: 899px) {
  /* styles.css sets `.section--center .offer-card { text-align: left }` at the
     same weight, so this needs two classes to win — features.css loads after. */
  .offer-list--demo .offer-card--demo { text-align: center; }
  .offer-card--demo .offer-card__icon svg { margin-inline: auto; }
  .offer-card--demo .offer-card__head { justify-content: center; }
  .offer-card--demo .offer-card__text > p,
  .offer-card--demo .offer-card__note { margin-inline: auto; }
  /* The list centres as a block but keeps its lines left-aligned — centring the
     bullets themselves leaves wrapped lines floating under a hanging dash. */
  .offer-card--demo .offer-card__points {
    display: inline-grid;
    text-align: left;
    justify-items: start;
  }
  /* The centring must not reach inside the devices — a phone screen's own
     content is left-aligned, whatever the card around it does. Elements that
     are deliberately centred (.call, .rate-sheet) set their own alignment. */
  .offer-list--demo .offer-card--demo .demo { text-align: left; }

  /* the section's own heading block is already centred by .section--center */
  .calc { text-align: left; }
}

/* =========================================================================
   TAP TARGETS + STICKY MOBILE ACTION BAR
   ========================================================================= */

/* The range track was a 6px-tall hit area. Keep the track thin visually but
   give the input a full 44px box to grab. */
.calc__slider {
  height: 44px;
  background: transparent;
  margin: var(--s2) 0 0;
}
.calc__slider::-webkit-slider-runnable-track {
  height: 6px;
  border-radius: 999px;
  background: linear-gradient(to right, var(--ockra) var(--pct, 20%), var(--border) var(--pct, 20%));
}
.calc__slider::-moz-range-track {
  height: 6px;
  border-radius: 999px;
  background: linear-gradient(to right, var(--ockra) var(--pct, 20%), var(--border) var(--pct, 20%));
}
.calc__slider::-webkit-slider-thumb { margin-top: -11px; }

/* Footer links and the wordmark also sat under 44px. */
.footer-facts a,
.orcall a,
.hero__reassure a { display: inline-block; padding-block: 0.7rem; }
.wordmark { display: inline-flex; align-items: center; min-height: 44px; }

/* ---- sticky action bar (phones only) ---- */
.mobile-bar { display: none; }
@media (max-width: 699px) {
  .mobile-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 60;
    display: flex;
    gap: 0.5rem;
    padding: 0.6rem 0.9rem calc(0.6rem + env(safe-area-inset-bottom));
    background: color-mix(in srgb, var(--kalk) 94%, transparent);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    border-top: 1px solid var(--border);
  }
  .mobile-bar a {
    flex: 1;
    min-height: 48px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    border-radius: var(--radius);
    font-family: var(--font-body);
    font-weight: 600;
    font-size: var(--step-0);
    text-decoration: none;
    border: 1.5px solid var(--gran);
  }
  .mobile-bar__call { color: var(--gran); background: transparent; flex: 0 0 40%; }
  .mobile-bar__call svg { width: 1em; height: 1em; stroke: var(--ockra); fill: none; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
  .mobile-bar__book { background: var(--gran); color: var(--on-dark); }
  /* clear the bar so it never covers the end of the footer */
  body { padding-bottom: 4.75rem; }
}


/* =========================================================================
   VERTICAL RHYTHM
   Ten sections at one identical interval read as a list, not a page. Short
   connective sections get pulled in; the destinations get room to breathe.
   Only these two modifiers exist — everything else keeps --section-y.
   ========================================================================= */
:root {
  --section-y-tight: clamp(2.5rem, 4.5vw, 3.75rem);
  --section-y-wide:  clamp(4rem, 8.5vw, 7.25rem);
}
.section.section--tight { padding-block: var(--section-y-tight); }
.section.section--wide  { padding-block: var(--section-y-wide); }


/* =========================================================================
   KONTAKT — the closing dark band
   Pris was the only dark section on the page, which read as a one-off. Giving
   the last section the same ground turns it into structure: the offer and the
   ask are both lifted, and the page closes into the footer instead of ending
   on the tenth stretch of greige. Mirrors .price-section exactly.
   ========================================================================= */
.section--dark {
  background: var(--gran);
  color: var(--on-dark);
}
/* .section + .section carries a light hairline at (0,2,0) — match it to win. */
.section.section--dark,
.section + .section.section--dark { border-top: none; }
.section--dark .eyebrow { color: var(--ockra); }
.section--dark h2 { color: var(--on-dark); }
.section--dark p,
.section--dark .muted { color: var(--on-dark-dim); }
.section--dark .lead { color: var(--on-dark); }
.section--dark a { color: var(--on-dark); }
.section--dark .link { text-underline-offset: 3px; }
.section--dark .cta-phone { color: var(--on-dark); }
.section--dark .cta-phone svg { stroke: var(--ockra); }
/* A light panel for the booking form — the embed paints its own light chrome
   and must not be asked to sit straight on the dark ground. */
.section--dark .contact__form {
  background: var(--papper);
  border-radius: var(--radius);
  padding: var(--s2);
}
.section--dark .form-skeleton { inset: var(--s2); }
/* The band runs into the equally dark footer; one hairline keeps the seam. */
.contact.section--dark { border-bottom: 1px solid rgba(238, 240, 234, 0.14); }
/* The lead sat flush against the h2; on the dark ground that reads as a
   wrapped headline rather than a sentence. */
.contact .lead { margin-top: var(--s3); }

/* --- a dark section that is NOT the last one on the page --------------- */
/* Mirrors .price-section: no light hairline or ockra tab on the seam below. */
.section--dark + .section { border-top: none; }
.section--dark + .section::before { display: none; }

/* A CTA block sitting straight on the dark ground (Tre steg) needs an
   inverted button — .btn is spruce on spruce otherwise. Still one CTA:
   the same button, flipped, not a second colour. */
.section--dark .section-cta p { color: var(--on-dark); }
.section--dark .section-cta .btn {
  background: var(--kalk);
  border-color: var(--kalk);
  color: var(--gran);
}
.section--dark .section-cta .btn:hover {
  background: #fff;
  border-color: #fff;
}
.section--dark .section-cta .btn svg { stroke: var(--gran); }
/* The step plates keep their own dark ink — they are light cards on dark. */
.section--dark .step p,
.section--dark .plate p { color: var(--gran); }
.section--dark .plate .muted { color: var(--dimma); }
/* A light card on the dark ground keeps its own dark ink (as .price-section). */
.section--dark .plate { color: var(--gran); }
/* .cta-phone__num sets its own colour, so inheritance from .section--dark
   never reaches it — flip it explicitly on the dark ground. */
.section--dark .section-cta .cta-phone { color: var(--on-dark-dim); }
.section--dark .section-cta .cta-phone__num { color: var(--on-dark); }
.section--dark .section-cta .cta-phone:hover { background: rgba(238, 240, 234, 0.07); }


/* =========================================================================
   HEADER ON PHONES — THE SWITCH
   Two behaviours are defined below and exactly one is active. This block is
   the switch: while `position: static` is here the header simply scrolls away
   with the page, and the retract code further down goes dormant on its own
   (features.js only retracts a header that is actually sticky). Delete this
   block to get the retract behaviour back — nothing else needs touching.
   ========================================================================= */
@media (max-width: 699px) {
  .site-header { position: static; }
  /* Nothing to lift off: a header that scrolls away has no page under it. */
  .site-header.is-scrolled { box-shadow: none; }
}

/* =========================================================================
   HEADER ON PHONES — retract on scroll (currently dormant, see switch above)
   Only below 700px, where .mobile-bar already carries the two actions.
   Desktop keeps the plain sticky header: there is no bottom bar there, so
   it is the only persistent CTA and must not move.
   Transform-based so nothing reflows while the page is being scrolled.
   ========================================================================= */
/*
 * NOTE — this uses `translate`, not `transform`, and must keep doing so.
 * styles.css runs `.site-header { animation: header-in 600ms ease both }`, and
 * that animation's last keyframe is `transform: none`. `animation-fill-mode:
 * both` keeps the keyframe applied for the life of the page, and declarations
 * from the animation origin outrank every author rule — inline styles included.
 * A `transform` here is therefore silently discarded. The standalone
 * `translate` property is composed separately, so it survives the animation
 * and the entrance flourish still plays.
 */
@media (max-width: 699px) {
  .site-header {
    transition: translate 260ms ease, box-shadow 220ms ease, background-color 220ms ease;
    will-change: translate;
  }
  .site-header.is-hidden { translate: 0 -100%; }
}
/* A header that slides is motion. When motion is unwelcome it simply stays. */
@media (prefers-reduced-motion: reduce) {
  .site-header { transition: box-shadow 220ms ease, background-color 220ms ease; }
  .site-header.is-hidden { translate: none; }
}
