/* Shared by every section: reset, layout, section frame and cards.
 * Section-specific rules live next to each section, in src/sections/<id>.css. */
* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 17px/1.6 var(--body);
  -webkit-font-smoothing: antialiased;
}

img {
  display: block;
  max-width: 100%;
}

a {
  color: inherit;
}

h1, h2, h3 {
  font-family: var(--heading);
  line-height: 1.15;
  margin: 0;
}

.wrap {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 20px;
}

.section {
  padding: 80px 0;
}

.section.alt {
  background: var(--surface);
}

/* A section highlighted in the builder: the theme's accent as its background
 * and accent-text as its text. Inside it the theme variables are remapped, so
 * every section's own styles follow: surfaces and lines are tints of the two,
 * buttons (--accent) are inverted. The copies (--hl-*) are taken on the
 * section and used by its children, since a variable can't be redefined from
 * itself on one element. */
.section.is-highlighted,
footer.is-highlighted {
  --hl-base: var(--accent);
  --hl-ink: var(--accent-text);
  /* The page's own surface, for the few things whose colours are only
   * readable on it (e.g. the offer's status badges). */
  --hl-paper: var(--surface);
  /* All the page's own colours, for a theme that keeps some content in them
   * inside highlighted sections (the Dark theme does it for tiles). */
  --pg-bg: var(--bg);
  --pg-surface: var(--surface);
  --pg-text: var(--text);
  --pg-muted: var(--muted);
  --pg-line: var(--line);
  --pg-accent: var(--accent);
  --pg-accent-text: var(--accent-text);
  --pg-highlight: var(--highlight);
  background: var(--hl-base);
  color: var(--hl-ink);
}

.section.is-highlighted > *,
footer.is-highlighted > * {
  --bg: var(--hl-base);
  --surface: color-mix(in srgb, var(--hl-ink) 10%, var(--hl-base));
  --text: var(--hl-ink);
  --muted: color-mix(in srgb, var(--hl-ink) 80%, var(--hl-base));
  --line: color-mix(in srgb, var(--hl-ink) 28%, var(--hl-base));
  --accent: var(--hl-ink);
  --accent-text: var(--hl-base);
  --highlight: var(--hl-ink);
  --logo-mono-filter: none;
}

/* Browsers without color-mix(): plain see-through tints instead. */
@supports not (color: color-mix(in srgb, red 50%, blue)) {
  .section.is-highlighted > *,
  footer.is-highlighted > * {
    --surface: rgba(127, 127, 127, .14);
    --muted: var(--hl-ink);
    --line: rgba(127, 127, 127, .4);
  }
}

/* Gloss: a highlighted section can also be glossy (class is-glossy). Two
 * layers over the accent: a 45° band of sheen in the highlight's ink colour,
 * which sweeps sideways with --gloss (0 → 1 as the section passes through the
 * screen, set by shared/gloss/: from beyond the right edge to beyond the left;
 * 0.5 = still, in the middle), and a fixed, faint shading from the
 * bottom-left corner that gives it depth. */
.section.is-highlighted.is-glossy,
footer.is-highlighted.is-glossy {
  background-image:
    linear-gradient(45deg,
      transparent 40%,
      color-mix(in srgb, var(--hl-ink) 10%, transparent) 46%,
      color-mix(in srgb, var(--hl-ink) 24%, transparent) 50%,
      color-mix(in srgb, var(--hl-ink) 10%, transparent) 54%,
      transparent 60%),
    linear-gradient(45deg,
      color-mix(in srgb, #000 14%, transparent),
      transparent 55%,
      color-mix(in srgb, #fff 6%, transparent));
  background-size: 300% 100%, 100% 100%;
  background-position: calc(var(--gloss, .5) * 100%) 0, 0 0;
  background-repeat: no-repeat;
}

@supports not (color: color-mix(in srgb, red 50%, blue)) {
  .section.is-highlighted.is-glossy,
  footer.is-highlighted.is-glossy {
    background-image:
      linear-gradient(45deg, transparent 40%, rgba(255, 255, 255, .1) 46%, rgba(255, 255, 255, .24) 50%, rgba(255, 255, 255, .1) 54%, transparent 60%),
      linear-gradient(45deg, rgba(0, 0, 0, .14), transparent 55%, rgba(255, 255, 255, .06));
  }
}

.section h2 {
  font-size: clamp(1.8rem, 3.5vw, 2.6rem);
  margin-bottom: 36px;
}

.section h2::after {
  content: "";
  display: block;
  width: 56px;
  height: 3px;
  background: var(--highlight);
  margin-top: 14px;
  border-radius: 2px;
}

.grid {
  display: grid;
  gap: 24px;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
}

.section.alt .card {
  background: var(--bg);
}

.media {
  aspect-ratio: 4/3;
  overflow: hidden;
  background: var(--line);
}

.media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .4s;
}

.card:hover .media img {
  transform: scale(1.04);
}

.body {
  padding: 20px 22px 24px;
}

.card h3 {
  font-size: 1.3rem;
}

.desc {
  color: var(--muted);
  margin-top: 10px;
}

.desc p {
  margin: 0 0 .6em;
}

@media (max-width: 640px) {
  .section {
    padding: 56px 0;
  }
}

/* Scroll reveal (shared/reveal/): elements marked data-reveal="left|right|up"
 * start shifted and transparent and glide into place once revealed. Only
 * under html.reveal-on, which the script sets, so without it nothing hides.
 * Items inside a data-reveal-group container are revealed together.
 * A section can tune --reveal-shift (distance) and --reveal-delay. */
.reveal-on [data-reveal] {
  opacity: 0;
  transition: opacity .8s ease, transform 1s cubic-bezier(.2, .7, .2, 1);
  transition-delay: var(--reveal-delay, 0s);
}

.reveal-on [data-reveal="left"] {
  transform: translateX(calc(-1 * var(--reveal-shift, 80px)));
}

.reveal-on [data-reveal="right"] {
  transform: translateX(var(--reveal-shift, 80px));
}

.reveal-on [data-reveal="up"] {
  transform: translateY(var(--reveal-shift, 40px));
}

.reveal-on [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
}

/* Things sliding in from the side must not widen the page meanwhile. */
.reveal-on .section:has([data-reveal]) {
  overflow-x: clip;
}

@media (max-width: 640px) {
  .reveal-on [data-reveal] {
    --reveal-shift: 40px;
  }
}

/* Intro: the same motion once as the page opens, for what is on screen from
 * the start (the banner's text). CSS only, so it needs no script and can't
 * flicker. data-intro="up"; --reveal-delay staggers it. */
[data-intro="up"] {
  animation: intro-up 1s cubic-bezier(.2, .7, .2, 1) var(--reveal-delay, 0s) both;
}

@keyframes intro-up {
  from {
    opacity: 0;
    transform: translateY(var(--reveal-shift, 32px));
  }
}

@media (prefers-reduced-motion: reduce) {
  .reveal-on [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }

  [data-intro] {
    animation: none;
  }
}
