/**
Theme Name: hanno.guide
Author: kaleidos:code GmbH
Author URI: https://www.kaleidoscode.de/
Description: Made by kaleidos:code
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: hanno-guide
Template: astra
*/

/* ==========================================================================
   1. Custom properties
   ========================================================================== */
:root {
  --shell-max: 72rem;
  --shell-gutter: 1.5rem;
  --button-font-size: 1.25rem;
}

/* Elementor defines its global colours on body.elementor-kit-5 rather than
   :root. These aliases must therefore share that scope. Fallbacks document
   each generated ID and keep the theme usable without Elementor. */
body {
  --brand: var(--e-global-color-8446d86, #d9373f);
  --brand-soft: var(--e-global-color-0c086ac, #fae7e8);
  --brand-soft-dark: var(--e-global-color-1ffb3f1, #f5d2d3);
  --brand-muted: var(--e-global-color-5aeaad6, #8b5255);
  --ink: var(--e-global-color-f7c54bc, #1a1416);
  --border: var(--e-global-color-6d649bf, #8b52554d);
  --on-brand: var(--e-global-color-c20b370, #ffffff);
}

/* ==========================================================================
   2. Base
   ========================================================================== */
html {
  font-size: clamp(1rem, calc(0.95625rem + 0.27344vw), 1.11125rem);
  scroll-behavior: smooth;
}

body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

p {
  hyphens: auto;
  text-wrap: pretty;
}

h1,
h2,
h3,
h4 {
  hyphens: auto;
  text-wrap: balance;
}

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

/* ==========================================================================
   3. Third-party overrides
   Keep global Astra and Elementor corrections here so they are easy to revisit
   after upgrades. Component-specific overrides stay with their component.
   ========================================================================== */

/* --- Astra ------------------------------------------------------------- */

/* Astra targets Elementor buttons as
   `body .elementor-button.elementor-size-sm` — one element + two classes
   (0,2,1) — which outranks Elementor's own kit rule
   `.elementor-kit-5 .elementor-button` (0,2,0). Every Elementor button
   carries a size class, so Astra always wins and the Site Settings value is
   ignored. Mirroring Astra's selector shape ties on specificity and wins on
   load order, because this stylesheet declares astra-theme-css as a
   dependency. */
body .elementor-button,
body .elementor-button.elementor-size-xs,
body .elementor-button.elementor-size-sm,
body .elementor-button.elementor-size-md,
body .elementor-button.elementor-size-lg,
body .elementor-button.elementor-size-xl {
  font-size: var(--button-font-size);
}

/* Astra underlines links inside post content. */
.ast-single-post .entry-content a,
.ast-comment-content a:not(.ast-comment-edit-reply-wrap a) {
  text-decoration: inherit;
}

.ast-article-single figure,
.ast-article-single img:not(figure img) {
  box-shadow: none;
}

/* --- Elementor --------------------------------------------------------- */

/* Elementor caps SVG files in Image widgets at 48px. The extra `.elementor`
   specificity restores their intrinsic width. Component rules can opt back
   into a fluid width when needed. */
.elementor .elementor-widget-image img[src$=".svg"] {
  width: auto;
}

.elementor-widget-image img {
  vertical-align: top;
}

/* In flex layouts, WebKit can use an inline SVG's intrinsic width when
   Elementor assigns width: 100%. Let width follow the controlled height and
   the SVG's intrinsic aspect ratio instead. */
.elementor svg {
  width: auto !important;
  display: block;
}

/* Prevent a final text block's default margin from stacking with a container
   gap. Cover both classic and Optimized Markup widget structures. */
.elementor-widget > *:last-child,
.elementor-widget > .elementor-widget-container > *:last-child {
  margin-block-end: 0;
}

/* ==========================================================================
   4. Layout utilities
   ========================================================================== */

.container-shell {
  width: 100%;
  max-width: var(--shell-max);
  margin-inline: auto;
  padding-inline: var(--shell-gutter);
}

.section-spacing {
  padding-block: 2.5rem;
}

.section-spacing-lg {
  padding-block: 4rem;
}

/* Elementor containers have no `width: auto` control. Keep both legacy class
   names until the saved page templates can be migrated to one alias. */
.m-flex-auto > .e-child,
.w-flex-auto > .e-child {
  width: auto;
}

/* Fractional layout dimensions can expose a subpixel seam between adjacent
   sections. Use only when the lower section starts with an opaque edge. */
.overlap-seam {
  margin-block-start: -1px;
}

.overflow-x-clip {
  overflow-x: clip;
}

.no-underline {
  text-decoration-line: none !important;
}

.push-up {
  margin-top: -0.125rem;
}

/* ==========================================================================
   5. Components
   Responsive rules use Elementor's default 767px mobile breakpoint.
   ========================================================================== */

/* --- Site header ------------------------------------------------------- */

/* Keep the mobile dropdown in document flow and anchor the desktop dropdown
   to the right edge of its trigger. */
.elementor-nav-menu--dropdown-mobile {
  position: static;
}

.elementor-nav-menu--dropdown {
  top: 100% !important;
  right: 0 !important;
  left: auto !important;
  width: max-content !important;
  margin-top: 0 !important;
  padding: 0.75rem;
  border-radius: 0.75rem;
}

.elementor-nav-menu--dropdown a {
  justify-content: flex-end;
  border-radius: 0.75rem;
  font-size: 1rem;
  line-height: 1.5;
}

/* --- Decorative divider ----------------------------------------------- */

/* The image is intentionally wider on small screens so its proportional
   height remains visually substantial. The wrapper crops the excess evenly. */
.divider {
  overflow: hidden;
}

.divider img {
  display: block;
  width: 100% !important;
  max-width: none !important;
  height: auto;
  margin-block-start: -1px;
}

@media (max-width: 767px) {
  .divider img {
    position: relative;
    left: 50%;
    width: 150% !important;
    transform: translateX(-50%);
  }
}

/* --- Labels ------------------------------------------------------------ */

.label {
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

/* --- Cards ------------------------------------------------------------- */

/* `.elementor` prefixes below are specificity, not scoping — they lift these
   rules over Elementor's own widget defaults. */
.elementor .card {
  box-shadow:
    0 1px 3px 0 rgb(0 0 0 / 0.1),
    0 1px 2px -1px rgb(0 0 0 / 0.1);
  transition:
    transform 200ms ease-out,
    box-shadow 200ms ease-out;
}

.elementor .card:hover {
  transform: translateY(-0.25rem);
  box-shadow:
    0 4px 6px -1px rgb(0 0 0 / 0.1),
    0 2px 4px -2px rgb(0 0 0 / 0.1);
}

.elementor .card-simple {
  position: relative;
  isolation: isolate;
}

.elementor .card-simple::after {
  position: absolute;
  z-index: -1;
  inset: 0;
  border-radius: inherit;
  background-color: transparent;
  content: "";
  pointer-events: none;
  transition: background-color 200ms ease-in-out;
}

.elementor .card-simple:hover::after {
  background-color: rgb(0 0 0 / 0.05);
}

.elementor .card-image img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.elementor .card-image-simple img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: center 90%;
}

@media (prefers-reduced-motion: reduce) {
  .elementor .card {
    transition: box-shadow 200ms ease-out;
  }

  .elementor .card:hover {
    transform: none;
  }
}

/* --- Buttons with a wipe-in overlay ------------------------------------ */

/* Each control contains its overlay in a local stacking context and clips
   whatever the overlay scales beyond its edges. */
.elementor-button,
.elementor-swiper-button,
.ast-scroll-top-icon {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  vertical-align: top;
}

/* A full-bleed tint parked at zero width until an interaction state scales it
   back up. It stays out of the hit test so it cannot swallow the button's own
   clicks. */
.elementor-button::before,
.elementor-swiper-button::before,
.ast-scroll-top-icon::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgb(255 255 255 / 0.15);
  transform: scaleX(0);
  pointer-events: none;
}

/* Only .effect-button widgets animate the tint, and they wipe it in from the
   left edge instead of growing it out of the centre. Carousel arrows and the
   scroll-to-top control deliberately keep the instant, centred version. */
.effect-button .elementor-button::before {
  transform-origin: left center;
  transition: transform 300ms ease-in-out;
}

/* A white tint is invisible on a light button, so darken it there instead. */
.effect-button.inverted .elementor-button::before {
  background: rgb(0 0 0 / 0.1);
}

/* Keyboard focus reveals the tint on every device, independently of the
   pointer capabilities the two queries below branch on. */
.elementor-button:focus-visible::before,
.elementor-swiper-button:focus-visible::before,
.ast-scroll-top-icon:focus-visible::before {
  transform: scaleX(1);
}

/* Hover is reserved for a real mouse or trackpad. Touch browsers synthesise
   :hover on tap and latch it until the next tap elsewhere, which otherwise
   leaves a tapped button tinted long after the finger is gone. */
@media (hover: hover) and (pointer: fine) {
  .elementor-button:hover::before,
  .elementor-swiper-button:hover::before,
  .ast-scroll-top-icon:hover::before {
    transform: scaleX(1);
  }
}

/* Coarse pointers get the tint as press feedback instead: on while the finger
   is down, gone on release. */
@media (hover: none), (pointer: coarse) {
  /* A 300ms wipe outlasts a typical tap, so drop it and show the tint at
     full width straight away. */
  .effect-button .elementor-button::before {
    transition: none;
  }

  .elementor-button:active::before,
  .elementor-swiper-button:active::before,
  .ast-scroll-top-icon:active::before {
    transform: scaleX(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .effect-button .elementor-button::before {
    transition: none;
  }
}

/* --- Taxonomy pills ---------------------------------------------------- */

.tour-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.tour-tag {
  padding: 0.25rem 0.75rem;
  border-radius: 9999px;
  background: var(--brand-soft-dark);
  color: var(--brand-muted);
  font-size: 0.8125rem;
}

/* Elementor keeps an empty Shortcode widget as a flex item. Hide its wrapper
   when the shortcode produced no tag list, preventing a phantom container gap. */
.tour-tags-widget:not(:has(.tour-tags)) {
  display: none;
}

/* --- Organic image mask ------------------------------------------------ */

/* Apply the mask to the image, not its widget wrapper, so the decorative
   compass pseudo-element remains outside the clipped area. */
.blob-image img {
  aspect-ratio: 1;
  object-fit: cover;
  -webkit-mask: url("/wp-content/uploads/2026/07/blob.svg") center / contain
    no-repeat;
  mask: url("/wp-content/uploads/2026/07/blob.svg") center / contain no-repeat;
}

/* Decorative artwork belongs in a pseudo-element and requires no alt text.
   Its offsets intentionally resolve against the positioned parent container;
   adding position: relative to this widget changes that coordinate system. */
.blob-image.with-compass::after {
  content: "";
  position: absolute;
  top: -4%;
  right: -27%;
  width: 60%;
  aspect-ratio: 1;
  background: url("/wp-content/uploads/2026/07/compass.svg") center / contain
    no-repeat;
  pointer-events: none;
}

/* --- Tour carousel ----------------------------------------------------- */

.tour-carousel .elementor-swiper-button {
  top: -2.5rem !important;
  display: grid !important;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 0.75rem;
  background: var(--brand);
  color: var(--on-brand) !important;
  font-size: 1.25rem !important;
  transition: background-color 150ms ease-out;
}

.tour-carousel .elementor-swiper-button-prev {
  right: 4.25rem !important;
  left: auto !important;
}

.tour-carousel .elementor-swiper-button-next {
  right: 0.75rem !important;
}

.tour-carousel .elementor-swiper-button.swiper-button-disabled {
  opacity: 0.35;
  pointer-events: none;
}

@media (max-width: 767px) {
  .tour-carousel .swiper-pagination {
    bottom: -0.75rem !important;
  }

  .tour-carousel .elementor-swiper-button {
    bottom: -3rem !important;
    top: auto !important;
    z-index: 11 !important;
  }

  .tour-carousel .elementor-swiper-button-prev {
    left: 0.75rem !important;
    right: auto !important;
  }

  .tour-carousel .elementor-swiper-button-next {
    right: 0.75rem !important;
  }
}
