/*
 * Homepage-only styles. Loaded from base.njk when `homePage` is set, so the
 * rest of the site does not pay for them.
 */

:root {
  --tile-radius: clamp(10px, 1.4vw, 16px);

  /* Hero photo */
  --photo-width: clamp(240px, 34vw, 440px);
  --photo-peek: 64dvh;
  --tilt-start: -9deg;
  --tilt-end: 4deg;
  --tilt-span-vh: 50;
}

/* The hero breaks out of the standard page padding. */
.page-main--home {
  width: 100%;
  max-width: none;
  padding: 0 0 clamp(1.25rem, 3vw, 2rem);
}

/* ================================================================ */
/* Hero                                                             */
/* ================================================================ */

.hero {
  display: grid;
  grid-template-rows: auto 1fr;
  min-height: var(--photo-peek);
}

.hero__spacer {
  height: clamp(5rem, 13vh, 8rem);
}

.hero__lead {
  align-self: end;
  /* Was an em-based measure, which resolved wider than the content
     column once that was capped at 620px. Tied to the same token now,
     with the size stepped down so the line still breaks in three. */
  width: min(100% - 2 * var(--frame), var(--content-max));
  margin: 0 auto;
  /* Bigger bottom gap = the copy sits higher, per the new mockup.
     Also clears the rotated top corner of the photo. */
  padding: 1rem 0 clamp(4rem, 13vh, 9rem);
  text-align: center;
  font-size: clamp(1.2rem, 2.2vw, 1.7rem);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.28;
  text-wrap: balance;
}

.hero-photo {
  display: flex;
  justify-content: center;
}

.hero-photo__frame {
  width: var(--photo-width);
  margin: 0;
  padding: clamp(8px, 1vw, 13px);
  border-radius: clamp(12px, 2vw, 20px);
  background: #fff;
  box-shadow:
    0 0 0 0.5px rgba(0, 0, 0, 0.05),
    0 12px 40px rgba(0, 0, 0, 0.12);
  /* Pivot about the top edge — that is the edge visible at the fold. */
  transform-origin: center top;
  transform: rotate(var(--tilt, var(--tilt-start)));
  will-change: transform;
}

.hero-photo__frame img {
  width: 100%;
  height: auto;
  border-radius: clamp(6px, 1.2vw, 11px);
}

/* ================================================================ */
/* Shared section furniture                                         */
/* ================================================================ */

.section {
  width: min(100% - 2 * var(--frame), var(--content-max));
  margin: 0 auto;
  padding-top: var(--section-gap);
}

.section__head {
  max-width: 34em;
  margin: 0 0 clamp(1.5rem, 3vw, 2.25rem);
}

.section__title {
  margin: 0 0 0.6rem;
  font-size: clamp(1.3rem, 2.4vw, 1.85rem);
  font-weight: 500;
  letter-spacing: -0.025em;
  line-height: 1.2;
}

.section__body {
  margin: 0;
  font-size: clamp(0.9375rem, 1.15vw, 1.0625rem);
  line-height: 1.55;
  color: var(--color-text-muted-hover);
}

/* Chunky rounded rect, not a flat pill: a lighter top edge, a darker
   lip inset along the bottom and a soft drop shadow give it depth. The
   lip is an inset shadow rather than a second element, so it follows
   the bottom corner radius. */
.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  /* `width: fit-content` + auto side margins centres it without making
     the whole section centre-aligned. */
  width: fit-content;
  margin: clamp(1.5rem, 3vw, 2.25rem) auto 0;
  padding: 0.8rem 1.65rem;
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: 12px;
  background: linear-gradient(180deg, #eb93c8 0%, var(--color-accent) 62%);
  color: #fff;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.25;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    inset 0 -4px 0 rgba(150, 44, 105, 0.28),
    0 6px 16px rgba(0, 0, 0, 0.16);
  transition:
    filter 0.16s ease,
    transform 0.18s ease,
    box-shadow 0.18s ease;
}

/* Lifts 2px on hover, with the drop shadow growing to match. */
.btn:hover {
  filter: brightness(1.05);
  transform: translateY(-2px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    inset 0 -4px 0 rgba(150, 44, 105, 0.28),
    0 10px 22px rgba(0, 0, 0, 0.18);
}

/* It looks pressable, so it should press — down past its resting spot. */
.btn:active {
  transform: translateY(1px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.4),
    inset 0 -2px 0 rgba(150, 44, 105, 0.28),
    0 2px 8px rgba(0, 0, 0, 0.14);
}

@media (prefers-reduced-motion: reduce) {
  .btn {
    transition: none;
  }

  .btn:hover,
  .btn:active {
    transform: none;
  }
}

.tile {
  position: relative;
  overflow: hidden;
  border-radius: var(--tile-radius);
  background: #f1f1f1;
}

.tile img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ================================================================ */
/* Bento                                                            */
/* ================================================================ */

.bento {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: clamp(0.5rem, 1vw, 0.85rem);
}

/* Three rows. The row heights come from aspect-ratio on the tiles that
   define them — A sets the taller top row, C and E are square — so the
   proportions hold at any width rather than needing per-breakpoint
   row heights. B and D stretch to fill. */
.bento__a { grid-column: 1 / 9;  grid-row: 1; aspect-ratio: 1.69; }
.bento__b { grid-column: 9 / 13; grid-row: 1; }
.bento__c { grid-column: 1 / 5;  grid-row: 2; aspect-ratio: 1; }
.bento__d { grid-column: 5 / 13; grid-row: 2 / 4; }
.bento__e { grid-column: 1 / 5;  grid-row: 3; aspect-ratio: 1; }

/* Taken out of flow so a tile contributes no intrinsic height: otherwise
   B's portrait source sets row 1 to its own 3:2 height (297px) instead
   of the 242px that A's ratio defines, and the two stop matching. */
.bento > .tile > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Crops: keep the subject the design frames, not the geometric centre. */
/* Design frames the green-bike rider alone, not the whole group,
   so this crop is pushed right and zoomed in. */
.bento__c img {
  object-position: 80% center;
  transform: scale(1.4);
}
.bento__e img { object-position: 38% center; }
.bento__b img { object-position: center 58%; }

/* The two route cards sit on a tinted ground, slightly tilted, so the
   tile reads as a composition rather than a flat screenshot. */
/* Two cards overlapping in depth, not a side-by-side pair: the right
   card is larger, sits higher and lies in front, and both lean the same
   way so they read as a stack. Positions are percentages of the tile so
   the arrangement holds as the tile resizes. Both run to the tile's
   bottom edge, where its overflow crops them. */
/* The tour cards are rebuilt as real markup rather than screenshots, so
   they stay sharp at any pixel density and cannot drift from the real
   component. Sizing works by container query: the card is a fixed
   300px design scaled by setting its font-size to a fraction of the
   tile width and expressing every internal value in em. That keeps
   proportions identical to the live 300px card at any tile size —
   and, unlike transform: scale(), never risks blurry rasterisation. */
.card-pair {
  position: relative;
  height: 100%;
  background: #ecebe9;
  container-type: inline-size;
}

.tcard {
  position: absolute;
  display: flex;
  flex-direction: column;
  background: var(--color-dark);
  color: #fff;
  border-radius: 1.25em;
  padding: 1.25em 1.25em 1.5em;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.24);
}

/* 18.75 = the live card's 300px width over its 16px root font size. */
.tcard--back {
  left: 4%;
  bottom: -3%;
  width: 52cqw;
  font-size: calc(52cqw / 18.75);
  transform: rotate(-3deg);
}

/* Anchored to the right edge rather than positioned from the left, so
   it stays pinned there whatever width it takes. */
.tcard--front {
  right: -3%;
  bottom: -3%;
  width: 62cqw;
  font-size: calc(62cqw / 18.75);
  transform: rotate(3deg);
}

.tcard__title {
  margin: 0 0 0.545em;
  font-size: 1.375em;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: -0.01em;
}

.tcard__summary {
  margin: 0 0 1.538em;
  font-size: 0.8125em;
  font-weight: 500;
  line-height: 1.45;
  opacity: 0.72;
}

.tcard__stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75em 1em;
  margin: 0 0 1em;
  padding: 0;
}

.tcard__stats div { margin: 0; }

.tcard__stats dt {
  margin: 0 0 0.267em;
  font-size: 0.75em;
  color: var(--color-text-muted-on-dark, #aaa);
}

.tcard__stats dd {
  margin: 0;
  font-size: 1em;
  font-weight: 500;
}

.tcard__chart {
  height: 5.5em;
  margin: 0 0 1em;
  overflow: hidden;
}

.tcard__chart svg {
  display: block;
  width: 100%;
  height: 100%;
}

.tcard__btn {
  display: block;
  width: 100%;
  padding: 0.907em 1.067em;
  border-radius: 0.667em;
  background: #fff;
  color: var(--color-text);
  font-size: 0.9375em;
  font-weight: 500;
  text-align: center;
}

.tcard__view {
  display: block;
  margin-top: 0.923em;
  font-size: 0.8125em;
  font-weight: 500;
  text-align: center;
  opacity: 0.85;
}

/* Tile A: the tour-detail card, inset from the tile's top-left and
   running past its right and bottom edges, where the tile crops it.
   Same container-query trick as the tour cards — a 560px design scaled
   by font-size, everything inside in em. */
.bento__a .tile-inner {
  position: relative;
  height: 100%;
  background: #f4f4f4;
  container-type: inline-size;
}

.tdetail {
  position: absolute;
  top: 8%;
  left: 9.5%;
  width: 90.5cqw;
  /* 37.5 = a 600px content width over the 16px root. Tuned so the map
     takes the same share of the visible card as in the design (~38%)
     once the tile crops the rest. */
  font-size: calc(90.5cqw / 37.5);
  padding: 1.5em;
  border-radius: 0.75em 0 0 0;
  background: #fff;
  color: var(--color-text);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.1);
}

.tdetail__eyebrow {
  margin: 0 0 0.431em;
  font-size: 0.8125em;
  font-weight: 500;
  color: var(--color-text-muted);
}

.tdetail__title {
  margin: 0 0 0.347em;
  font-size: 1.875em;
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.02em;
}

.tdetail__summary {
  margin: 0;
  font-size: 0.9375em;
  line-height: 1.5;
  opacity: 0.78;
}

/* 4 columns above 520px on the live page, which this design width is. */
.tdetail__stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.75em 1em;
  margin: 1.25em 0;
  padding: 0;
}

.tdetail__stats div { margin: 0; }

.tdetail__stats dt {
  margin: 0 0 0.2em;
  font-size: 0.75em;
  color: var(--color-text-muted);
}

.tdetail__stats dd {
  margin: 0;
  font-size: 1em;
  font-weight: 500;
}

/* Map: six 256px OSM tiles positioned by percentage, so the mosaic
   scales fluidly and the route SVG stays aligned to it. */
.tdetail__map {
  position: relative;
  aspect-ratio: 768 / 512;
  overflow: hidden;
  border: 1px solid #ececec;
  border-radius: 0.75em;
}

.tmap__tile {
  position: absolute;
  max-width: none;
}

.tmap__route {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* Top-right, not bottom-right: the tile crops the map's lower half, and
   OSM tiles require the attribution to stay visible. */
.tmap__attr {
  position: absolute;
  right: 0;
  top: 0;
  padding: 0.15em 0.4em;
  background: rgba(255, 255, 255, 0.72);
  font-size: 0.5em;
  color: #444;
}

/* ================================================================ */
/* "Touren sind für alle da"                                        */
/* ================================================================ */

.duo {
  display: grid;
  grid-template-columns: 1fr 1.35fr;
  gap: clamp(0.5rem, 1vw, 0.85rem);
  height: clamp(180px, 30vw, 250px);
}

/* ================================================================ */
/* Velorino                                                         */
/* ================================================================ */

/* Design measures roughly 2.17:1, not the 1.3:1 this had. Height comes
   from the phones tile's aspect ratio, so the icon tile stretches to
   match instead of both needing a hand-set height. */
.velorino {
  display: grid;
  grid-template-columns: 2.17fr 1fr;
  gap: clamp(0.5rem, 1vw, 0.85rem);
}

.velorino__phones {
  position: relative;
  aspect-ratio: 805 / 475;
  background: #ececec;
}

/* Both phones hang from the top and run past the tile's bottom edge,
   where its overflow crops them — as in the design.

   The sources are JPEGs with a white ground baked in, so the device's
   rounded corners came out as white triangles against the tile. The
   side margin is cropped off the files; this radius clips what the
   rounding leaves. It is stated as two percentages (of width / of
   height) rather than one, because a single percentage resolves per
   axis and would draw an ellipse on a 630x1311 box — 87px of each
   gives 13.8% and 6.6%. */
.velorino__phones img {
  position: absolute;
  top: 5%;
  width: 31%;
  height: auto;
  max-width: none;
  border-radius: 13.8% / 6.6%;
}

/* Fanned apart, not parallel — the pair leans away from each other the
   same way the two tour cards do. */
.velorino__phones img:first-child {
  left: 15%;
  transform: rotate(-3deg);
}

.velorino__phones img:last-child {
  left: 54%;
  transform: rotate(3deg);
}

/* The icon source is 16:9 but the tile is portrait. Plain `cover` alone
   leaves the icon too small — this crops *and* scales in, so the icon
   fills the tile the way the design shows. Still a downscale from the
   1200px source, so it stays sharp. */
.velorino > .tile:last-child img {
  transform: scale(1.45);
}

.app-store-badge {
  display: block;
  width: fit-content;
  margin: clamp(1.5rem, 3vw, 2.25rem) auto 0;
  transition:
    opacity 0.2s ease,
    transform 0.18s ease;
}

.app-store-badge:hover {
  opacity: 0.85;
  transform: translateY(-2px);
}

.app-store-badge img {
  height: 44px;
  width: auto;
  aspect-ratio: 132 / 44;
}

/* ================================================================ */
/* Personal intro                                                   */
/* ================================================================ */

.intro {
  display: flex;
  align-items: center;
  gap: clamp(1.5rem, 4vw, 3.5rem);
}

/* Frame is ~34% of the row in the design, with an even border rather
   than the bottom-heavy polaroid this had. Padding is a fixed length,
   not a percentage: percentage padding resolves against the containing
   block's width, not the element's, so 3.8% here meant 3.8% of the
   620px row — 23px instead of the intended 8px. */
.intro__photo {
  flex: none;
  width: clamp(150px, 34%, 235px);
  margin: 0;
  padding: 8px;
  border-radius: 14px;
  background: #fff;
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.06),
    0 14px 34px rgba(0, 0, 0, 0.16);
  transform: rotate(-5deg);
}

/* The source is a 2:3 portrait with a lot of sky above and path below.
   Cropping to near-square and letting `cover` do the work zooms in on
   Philipp; the position bias keeps his head off the top edge. */
.intro__photo img {
  width: 100%;
  aspect-ratio: 0.95;
  height: auto;
  object-fit: cover;
  object-position: center 64%;
  border-radius: 6px;
}

.intro__text {
  margin: 0;
  font-size: clamp(0.9375rem, 1.2vw, 1.0625rem);
  line-height: 1.6;
  color: var(--color-text-muted-hover);
}

.intro__text a {
  color: var(--color-text);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.intro__text a:hover {
  color: var(--color-accent-dark);
}


/* ---------------------------------------------------------------------- */
/* Phone                                                                   */
/* ---------------------------------------------------------------------- */

@media (max-width: 620px) {
  :root {
    --photo-width: min(76vw, 320px);
    --photo-peek: 60dvh;
  }

  .velorino {
    grid-template-columns: 1fr;
  }

  .velorino__phones img {
    width: 40%;
  }

  .velorino__phones img:first-child { left: 8%; }
  .velorino__phones img:last-child { left: 52%; }

  .velorino > .tile:last-child {
    aspect-ratio: 2 / 1;
  }

  /* Bento: 12 cols → 2. Tiles are placed explicitly so each image gets a
     shape that suits it: the two UI tiles keep full width (they stop being
     legible narrow), the landscape photo takes a wide strip, and the two
     portrait photos pair up as a tall duo. */
  .bento {
    grid-template-columns: repeat(2, 1fr);
    grid-auto-rows: clamp(102px, 27vw, 150px);
  }

  .bento__a,
  .bento__c,
  .bento__e {
    aspect-ratio: auto;
  }

  .bento__a { grid-column: 1 / 3; grid-row: 1 / 3; }
  .bento__e { grid-column: 1 / 3; grid-row: 3 / 4; }
  .bento__b { grid-column: 1 / 2; grid-row: 4 / 6; }
  .bento__c { grid-column: 2 / 3; grid-row: 4 / 6; }

  /* Three rows, not two: at two the tile is too short for the tour cards
     and the front card's title gets clipped off the top. */
  .bento__d { grid-column: 1 / 3; grid-row: 6 / 9; }

  .duo {
    height: clamp(180px, 52vw, 260px);
  }

  .intro {
    flex-direction: column;
    align-items: flex-start;
    gap: 1.5rem;
  }

  .intro__photo {
    width: 58%;
  }

}

@media (prefers-reduced-motion: reduce) {
  /* Must come after .app-store-badge's own rules: same specificity, so
     source order decides. */
  .app-store-badge {
    transition: none;
  }

  .app-store-badge:hover {
    transform: none;
  }
}
