/* ------------------------------------------------------------------
   Ripple Residence - UX fixes
   Added 2026-09-15. Loaded from functions.php after the theme styles.

   Additive only: this file overrides, it never replaces. Remove the
   wp_enqueue_style('rr-ux-fixes') call in functions.php to roll the
   whole thing back in one line.
   ------------------------------------------------------------------ */

/* 1. iOS/iPadOS zoom on focus -------------------------------------
   The root is font-size:62.5%, so 1rem = 10px and a field declared
   1.25rem computes to 12.5px. Safari zooms the viewport on any field
   under 16px. A partial fix shipped 2026-09-03 in snippet 5304, but it
   covered only .de-form and gated on (pointer: coarse).

   Two gaps are closed here:
   - `any-pointer` instead of `pointer`. `pointer` describes the
     device's PRIMARY input, so an iPad with a keyboard case reports
     `fine` and falls out of the query - on exactly the device the
     clause was added for.
   - the plugin forms (boligvaelger, popups) were never covered,
     although they are the ones the original comment called the worst
     case, because a zoom there shifts the whole panel.
   16px is never wrong on a field; it is only sometimes larger than
   the design drew.                                                  */
@media (max-width: 767px), (any-pointer: coarse) {
  input[type="text"],
  input[type="email"],
  input[type="tel"],
  input[type="url"],
  input[type="number"],
  input[type="search"],
  input[type="password"],
  input[type="date"],
  select,
  textarea,
  input[type="text"]::placeholder,
  input[type="email"]::placeholder,
  input[type="tel"]::placeholder,
  input[type="search"]::placeholder,
  textarea::placeholder {
    font-size: 16px !important;
  }
}

/* 2. The interest-list form ----------------------------------------
   Placeholders were the only labels, so the field name and the
   required marker both vanished the moment you typed. ux-fixes /
   snippet 5283 now render a real <label> above every field. A static
   label is used rather than a floating one on purpose: nothing moves
   on focus, so there is no jump and no padding trickery.            */
.de-form .rr-field {
  margin: 0 0 1.6rem;
}
.de-form .rr-field > label {
  display: block;
  margin: 0 0 .5rem;
  font-size: 1.4rem;
  line-height: 1.3;
  color: var(--rr-text, #001414);
}
.de-form .rr-field > label .rr-req {
  color: #b3261e;
  margin-left: .2em;
}

/* inline errors: one per field, all shown at once, instead of the
   browser's single bubble on the first invalid field */
.de-form .rr-error {
  display: none;
  margin: .5rem 0 0;
  font-size: 1.3rem;
  line-height: 1.4;
  color: #b3261e;
}
.de-form .rr-field.has-error .rr-error {
  display: block;
}
.de-form .rr-field.has-error input,
.de-form .rr-field.has-error textarea {
  border-color: #b3261e;
}

/* The consent row was 11.25px text in a 12x12px box.
   Note the `label.rr-consent` selector: snippet 5135 sets the same
   property from a stylesheet that loads in the FOOTER, so a plain
   `.de-form .rr-consent` ties on specificity and loses on source
   order. The element qualifier breaks the tie without !important. */
.de-form label.rr-consent {
  font-size: 1.4rem;
  line-height: 1.5;
  align-items: flex-start;
  gap: 1.2rem;
  padding: .8rem 0;
  color: var(--rr-text, #001414);
}
.de-form label.rr-consent > span {
  font-size: 1.4rem;
}
.de-form .rr-consent input[type="checkbox"] {
  width: 2.2rem;
  height: 2.2rem;
  margin-top: .1rem;
  flex: 0 0 auto;
}
/* a 44px touch target without drawing a 44px box */
@media (max-width: 767px), (any-pointer: coarse) {
  .de-form label.rr-consent input[type="checkbox"] {
    box-sizing: content-box;
    padding: 11px;
    margin: -11px -11px -11px 0;
  }
  .de-form label.rr-consent { gap: 2.3rem; }
}

/* 3. Touch targets --------------------------------------------------
   44x44 is the floor for anything with no design frame behind it.    */
@media (max-width: 767px), (any-pointer: coarse) {
  .menu.primary .menu-item > a,
  .menu.secondary a {
    display: block;
    min-height: 44px;
    line-height: 44px;
  }
  .de-form button[type="submit"],
  .wp-block-button__link,
  .button.border {
    min-height: 44px;
  }
}

/* 4. Fixed elements colliding ---------------------------------------
   Weglot's language selector is fixed in the bottom-right corner at
   z-index 9999 and lands on top of the boligoversigt "Aabent Hus"
   bar, cutting its label mid-word. Snippet 5303 solved it on the
   boligvaelger only (page-id 57) by hiding the selector there; every
   other page still collided.

   The bar is the client's CTA and the selector is a utility, so the
   bar keeps the corner and is simply lifted clear of it. Do NOT cap
   the bar's width to dodge the selector: the header text then wraps
   to three lines inside a pill whose height does not grow, and the
   first line spills out above it.

   The bar is anchored to the bottom, so it expands upwards and the
   gap below it is kept whether it is collapsed or open.             */
/* NOT by lifting the bar: the plugin collapses it by pushing the
   panel down past the bottom edge of the viewport, so raising the
   overlay by 54px simply reveals 54px of the panel that is supposed
   to be hidden. The selector is the thing that has to move. */
/* NOTE: rem is 10px on this site (html { font-size: 62.5% }), so the
   first version of this rule - left:2rem; bottom:1.5rem - rendered as
   20px/15px, not 32px/24px. Values are stated in px here so the next
   reader is not caught by the same thing.
   The cookie consent widget is in this corner too: cookie-admin has
   widgetPosition "bottom-left" and the SDK pins it at left:10px,
   bottom:10px, 40x40, z-index 999997. Its position is configuration,
   not site code, so the corner belongs to it and the selector stacks
   ABOVE it - left edges aligned, 10px of air between them. */
.country-selector.weglot-dropdown {
  right: auto;
  left: 10px;
  bottom: 60px;
}
/* On a phone the bar spans nearly the full width, so the bottom-left
   corner is inside it. Sit above the bar instead. The panel is hidden
   below the fold while collapsed and only expands on a deliberate tap,
   so overlapping it while open is acceptable. */
@media (max-width: 767px) {
  .country-selector.weglot-dropdown {
    bottom: 66px; /* 6.6rem; unchanged in value, see the note above */
  }
}

/* The bar's own label spills out of its pill. The heading carries
   padding:36px on all four sides, so its box is 95px tall inside a
   header strip that is 50px - the plugin then lifts the container
   with a transform and the surplus sticks out above the pill. On a
   narrower viewport the same padding squeezes the text into three
   lines, which is what makes it look broken.
   Measured on the LIVE site before any of this file existed: the
   heading overflows the pill by 22px, so this is not a regression
   from the lift above. The text itself needs only 224px.
   The culprit is styling-indstillinger.css:
     #popup-overlay .popup-header-container .popup-header-heading
     { padding: 10%; }
   A PERCENTAGE padding resolves against the containing block's WIDTH
   on all four sides, so 10% of 360px is 36px top and bottom too. The
   selector below repeats the plugin's own, so it ties on specificity
   and wins on source order without !important.
   That value probably comes from a styling setting in the plugin
   admin - I have not verified which page, so the durable fix is
   Kevin's call; this is a site-level override. */
#popup-overlay .popup-header-container .popup-header-heading {
  padding: 1.3rem 2.4rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 5. Image carousel --------------------------------------------------
   12 slides with no arrows, no dots and no keyboard access. The only
   affordance was a drag cursor that appears once you are already
   hovering. ux-fixes.js adds real controls driven by Swiper's own API;
   this styles them.                                                   */
.large-image-carousel {
  position: relative;
}
.large-image-carousel .rr-swiper-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 5;
  width: 48px;
  height: 48px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, .92);
  color: #001414;
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: background .15s ease, opacity .15s ease;
}
.large-image-carousel .rr-swiper-nav:hover {
  background: #fff;
}
.large-image-carousel .rr-swiper-nav[disabled] {
  opacity: .35;
  cursor: default;
}
.large-image-carousel .rr-swiper-nav.is-prev { left: 2rem; }
.large-image-carousel .rr-swiper-nav.is-next { right: 2rem; }
.large-image-carousel .rr-swiper-nav svg { width: 20px; height: 20px; }

.large-image-carousel .rr-swiper-dots {
  display: flex;
  justify-content: center;
  gap: 1.4rem;
  margin-top: 1.6rem;
}
.large-image-carousel .rr-swiper-dots button {
  position: relative;
  width: 8px;
  height: 8px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 20, 20, .25);
  cursor: pointer;
  transition: background .15s ease, transform .15s ease;
}
.large-image-carousel .rr-swiper-dots button[aria-current="true"] {
  background: #001414;
  transform: scale(1.4);
}
/* The touch target is a transparent pseudo element. Padding plus
   background-clip does not work here: on a round 8px button the
   padding inflates the background box and the active dot renders as
   a large dark oval instead of a dot. */
.large-image-carousel .rr-swiper-dots button::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 22px;
  height: 34px;
  transform: translate(-50%, -50%);
}
.large-image-carousel .rr-swiper-dots button:focus-visible {
  outline: 2px solid #001414;
  outline-offset: 6px;
}
@media (max-width: 767px) {
  .large-image-carousel .rr-swiper-nav { display: none; }
}

/* 8. Hero content, vertically centred -------------------------------
   Top to bottom ONLY. The text keeps its left alignment and the
   container keeps its centred max-width, which is what gives the left
   gutter - so contentPosition stays "center center" and nothing here
   touches text-align.
   The block attribute alone is not enough: the hero block's own CSS
   sets align-self on the inner container (end for .bottom, start for
   .top) and a page-scoped inline rule raises that further, so this
   needs to out-specify both.                                        */
.page-id-1384 section.hero .wp-block-cover.is-position-center-center .wp-block-cover__inner-container,
.hero .wp-block-cover.is-position-center-center .wp-block-cover__inner-container {
  align-self: center;
}

/* 6. Hero video ------------------------------------------------------
   core/cover renders the video without a poster, so the hero is an
   empty dim box until the first frame decodes.                        */
.hero .wp-block-cover__video-background {
  object-fit: cover;
  width: 100%;
  height: 100%;
}
/* the video is a 16:9 landscape crop; on a tall phone hero the centre
   is all that survives, so bias the crop towards the skyline */
@media (max-width: 767px) {
  .hero .wp-block-cover__video-background {
    object-position: 60% 50%;
  }
}

/* 7. Burger menu -----------------------------------------------------
   ux-fixes.js turns the label into a real button; it needs a visible
   focus ring, which the bare label never had.                         */
label[for="menu-input"]:focus-visible {
  outline: 3px solid currentColor;
  outline-offset: 3px;
}

/* 9. Language selector moved into the footer -------------------------
   Three fixed things were stacking in the bottom corners: the
   boligoversigt "Aabent Hus" bar (the client's CTA), the cookie widget
   (a legal control that has to stay findable, and our SDK exposes no
   way to open it from anywhere else) and the language selector. The
   selector is the only one of the three that can move, so it moves.
   ux-fixes.js MOVES Weglot's own element into .rr-lang-slot rather
   than rendering a second one, so the markup, links and behaviour are
   the plugin's. If that fails the element stays where Weglot put it
   and section 4's corner rules still apply, so the fallback is the
   previous behaviour and not a missing selector.                      */
.rr-lang-slot {
  display: flex;
  justify-content: flex-start;
  margin-top: 1.5rem;
}

/* The "Aabent Hus" bar is position:fixed and 49px tall, so it covers
   the last ~50px of every page. Measured overlapping the selector on
   both phone and desktop. This is the bar's own height plus air. */
footer {
  padding-bottom: 70px;
}

/* Below the desktop breakpoint the whole bottom row goes left, like
   every other column in this footer.
   ⚠ The credit <p> carries an INLINE style="text-align: center" from
   the footer_bottom field in WordPress, and an inline style beats any
   stylesheet short of !important. It is deliberately NOT overridden:
   the theme centres the row with align-items:center, so once that is
   flex-start and the auto side margins are gone, the <p> box shrinks
   to its own text and centring inside a box that tight has nothing
   left to do. The inline style stays where an editor can see it. */
@media (max-width: 767px) {
  footer .container.footer-container.rr-footer-bottom {
    align-items: flex-start;
  }
  footer .container.footer-container.rr-footer-bottom > p {
    margin-inline: 0;
    /* ⚠ The ONE !important in this file, and it is the correct use of
       it: the credit <p> carries style="text-align: center" written
       directly on the element by the footer_bottom field in WordPress,
       and an inline style cannot be beaten by specificity at all.
       Assuming the box would shrink to its text under align-items was
       wrong - measured 332px wide against 157px of text, so the inline
       centring still had room to act.
       The tidier fix is to drop `text-align: center` from that field in
       wp-admin, which is a content change and not ours to make
       unasked. If that is ever done, this rule can go. */
    text-align: left !important;
  }
}

/* From the desktop breakpoint the bottom row is put on the SAME
   12-column grid the row above already uses, so the selector lands in
   the identical column as the "Det med småt" / THE FINE PRINT block
   instead of hanging 208px further right against the container edge -
   which is what made the footer's right side look broken. Measured off
   the theme's own grid: 12 tracks, 26px gap, and that block is
   col-lg-2 at columns 9-10. Reproducing the grid rather than
   hardcoding 208px keeps it lined up at every width.

   ⚠ SPECIFICITY, not !important. custom.min.css owns this container:
     footer .container:last-of-type      { flex-direction: column }   (0,2,1)
     footer .container:last-of-type > p  { margin-inline: auto }      (0,2,2)
   These selectors carry one class more, the smallest thing that wins,
   and leave the theme's own rules intact everywhere else. */
@media (min-width: 768px) {
  footer .container.footer-container.rr-footer-bottom {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    column-gap: 26px;
    align-items: center;
  }
  /* The credit spans the whole row and is centred in it, so it keeps
     its true page centre instead of being centred in whatever is left
     beside the selector. Both sit on grid row 1; the credit box
     shrinks to its own text, so the two never meet. */
  footer .container.footer-container.rr-footer-bottom > p {
    grid-column: 1 / -1;
    grid-row: 1;
    justify-self: center;
    margin: 0;
  }
  footer .container.footer-container.rr-footer-bottom .rr-lang-slot {
    grid-column: 9 / 11;
    grid-row: 1;
    justify-content: flex-start;
    margin-top: 0;
  }
}

.rr-lang-slot .country-selector {
  /* ⚠ RELATIVE, never static. Weglot's panel is position:absolute and
     resolves against its nearest POSITIONED ancestor. Setting this to
     static removes it from that chain, so the panel anchors to a
     wrapper far up the page - it still opens, it is simply rendered
     thousands of pixels away, which on screen is indistinguishable
     from a dead button. Measured once: panel top -7624px. */
  position: relative;
  inset: auto;
  z-index: auto;
  display: inline-block;
}

/* The footer sits at the bottom of the document, so the panel has to
   open upwards or it opens off-screen. Weglot adds .weglot-invert by
   its own measurement; assert it rather than depend on where the
   element happened to be when the plugin measured. */
.rr-lang-slot .country-selector.weglot-dropdown ul {
  bottom: 100%;
  top: auto;
}

/* ⚠ In the footer the panel's links inherit the FOOTER's link colour,
   which is white, and Weglot's panel background is white - so
   "English" rendered white on white. It was in the DOM the whole time,
   which is why it read as a dead control rather than a styling bug.
   Measured: rgb(255,255,255) on rgb(255,255,255). Pinned to the colour
   the current-language row already uses on this site, so no new colour
   is introduced. */
.rr-lang-slot .country-selector.weglot-dropdown ul a,
.rr-lang-slot .country-selector.weglot-dropdown ul a:link,
.rr-lang-slot .country-selector.weglot-dropdown ul a:visited,
.rr-lang-slot .country-selector.weglot-dropdown ul a:hover,
.rr-lang-slot .country-selector.weglot-dropdown ul a:focus {
  color: rgb(0, 20, 20);
}
