/* ==========================================================================
   The Fix Center — hero.css
   Dark cinematic hero (reference vibe: sharebien.com — original implementation).
   Masked line-reveal headline, pointer-tilt image panel, kinetic marquee,
   pinned caption + price overlays, drifting solder glow. Motion is compositor-
   friendly (transform / opacity only) and fully disabled under reduced-motion.
   ========================================================================== */

/* The picker used to hang below the hero's bottom edge and over the section
   beneath it; it now sits under the search instead, so there is nothing to
   overhang. Kept at 0 rather than deleted because .reparaties (sections.css)
   still reads it for its top padding — one value to change if the overlapping
   treatment is ever wanted back. */
:root { --pick-overlap: 0px; }

.hero {
  position: relative;
  isolation: isolate;
  padding-top: 74px;                 /* clear the fixed header */
  /* Not `overflow: clip` any more — the picker is meant to escape the box. */

  /* The rest of the site is dark text on light surfaces, so --fg is near-black.
     The hero is now the one place that inverts: its content sits on a dark
     scrim over the workshop photo. Rebinding the three text tokens locally
     flips every descendant at once, instead of overriding `color` on each rule
     and missing one. Surface tokens (--paper, --ink, --line) are deliberately
     NOT rebound: the search pill and the picker cards are light cards sitting
     ON the photo and must keep their light-surface colours.
     Accent stays the vivid orange — it clears 4.5:1 on this scrim. */
  --fg:      oklch(97% 0.006 85);
  --fg-dim:  oklch(87% 0.008 80);
  --fg-mute: oklch(75% 0.01 78);
  color: var(--fg);
}

/* ---------- full-bleed workshop photo ----------
   The photo is the hero's background now rather than a side panel, so the
   headline and search sit on top of it. Everything above it needs a scrim
   dark enough for white text at AA, which is why the image is deliberately
   pushed down in contrast rather than shown at full strength. */
.hero__media { position: absolute; inset: 0; z-index: -2; overflow: hidden; }
.hero__media img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 38%;
  /* Slow drift so a still photo doesn't feel like a dead backdrop. */
  animation: heroPan 26s var(--ease) infinite alternate;
}
.hero__scrim {
  position: absolute; inset: 0;
  background:
    radial-gradient(120% 90% at 50% 12%, oklch(30% 0.06 55 / 0.28) 0%, transparent 62%),
    linear-gradient(180deg, oklch(18% 0.03 55 / 0.86) 0%, oklch(18% 0.03 55 / 0.68) 42%, oklch(20% 0.03 55 / 0.9) 100%);
}
.hero__grain {
  position: absolute; inset: -20%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
  opacity: 0.06;
  mix-blend-mode: overlay;
}

/* ---------- centred column ---------- */
.hero__center {
  position: relative;
  display: grid; justify-items: center; text-align: center;
  max-width: 62rem; margin-inline: auto;
  padding-block: clamp(2.2rem, 5vh, 3.8rem) clamp(1.8rem, 3.5vh, 2.8rem);
}

/* .hero__eyebrow / .hero__pin lived here — the "Reparatie & micro-soldeerwerk
   · Den Haag" pill above the headline. Markup and styles both removed so the
   space goes to the category cards. */

.hero__title {
  /* Deliberately smaller than --text-hero. That token was sized for the old
     two-column layout where the headline WAS the hero; here the search field is
     the main action, and a 105px centred headline pushed it below the fold. */
  font-size: clamp(2.4rem, 1rem + 4.1vw, 4.3rem);
  letter-spacing: -0.035em;
  line-height: 1;
  margin-bottom: 1.1rem;
  max-width: 18ch;
}
/* each line masked; inner slides up on load (JS adds .hero.ready).
   Hidden start gated on html.js so the headline shows without scripts. */
.hero__title .line { display: block; overflow: hidden; padding-bottom: 0.16em; }
.hero__title .line > span { display: block; }
.js .hero__title .line > span {
  transform: translateY(110%) rotate(2deg);
  transition: transform 900ms var(--ease-out-expo);
  transition-delay: calc(var(--ln, 0) * 110ms + 150ms);
}
.hero.ready .hero__title .line > span { transform: none; }
.hero__title .accent {
  color: var(--accent);
  position: relative;
  white-space: nowrap;
}
.hero__title .accent::after {
  content: "";
  position: absolute; left: 0; bottom: 0.02em; width: 100%; height: 0.07em;
  background: var(--accent);
  transform: scaleX(0); transform-origin: left;
  transition: transform 700ms var(--ease) 950ms;
}
.hero.ready .hero__title .accent::after { transform: scaleX(1); }

.hero__sub {
  font-size: var(--text-lead);
  color: var(--fg-dim);
  max-width: 46ch;
  margin-bottom: 1.8rem;
}
.hero__sub b { color: var(--fg); font-weight: 600; }

.hero__actions { display: flex; flex-wrap: wrap; gap: 0.9rem; margin-bottom: 2.6rem; }

/* margin-inline: auto is the fix for the row sitting off to the left. The
   badges used to live inside .hero__center, a grid with justify-items: center,
   which centred them for free. Moving them out into a plain .container left
   the `width: min(100%, 46rem)` box hard against the left gutter — the items
   were centred inside a box that was itself not centred. */
.hero__trust {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-start;
  gap: 1.2rem 2rem;
  padding-top: 1.8rem;
  border-top: 1px solid color-mix(in oklch, white 18%, transparent);
  width: 100%;
  margin-inline: auto;
}
/* Equal shares of the row. Capped at 52rem the three badges did not fit side
   by side — their labels are full sentences — so they wrapped into a stacked
   column, which is what read as "not centred as a row". Letting each take a
   third of the full container keeps them on one line. */
@media (min-width: 860px) {
  .hero__trust-item { flex: 1 1 0; min-width: 0; max-width: 24rem; }
}
.hero__trust-item {
  display: grid; gap: 0.15rem;
  grid-template-columns: auto 1fr; grid-template-areas: "ico num" "ico lbl";
  align-items: center; column-gap: 0.65rem; text-align: left;
}
.hero__trust-item .ico {
  grid-area: ico; display: grid; place-items: center;
  width: 34px; height: 34px; border-radius: 10px;
  color: var(--accent);
  background: color-mix(in oklch, var(--accent) 18%, transparent);
  border: 1px solid color-mix(in oklch, var(--accent) 28%, transparent);
}
.hero__trust-item .num {
  grid-area: num;
  font-family: var(--font-display); font-weight: 700; font-size: 1.15rem;
  color: var(--fg); letter-spacing: -0.02em;
}
.hero__trust-item .lbl { grid-area: lbl; }
.hero__trust-item .num .accent { color: var(--accent); }
.hero__trust-item .lbl {
  font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--fg-mute);
}

/* ---------- search ----------
   The widest, brightest thing in the hero: on a repair site the first question
   is always "do you do MY phone", and this answers it in one move. */
.hero__search {
  position: relative;
  display: flex; align-items: center; gap: 0.5rem;
  width: min(100%, 46rem);
  margin-bottom: 1rem; padding: 0.45rem 0.45rem 0.45rem 3.1rem;
  border-radius: 999px;
  background: var(--paper);
  box-shadow: 0 18px 44px oklch(18% 0.03 55 / 0.34), 0 0 0 1px color-mix(in oklch, white 22%, transparent);
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.hero__search:focus-within {
  transform: translateY(-2px);
  box-shadow: 0 22px 52px oklch(18% 0.03 55 / 0.4), 0 0 0 3px var(--accent);
}
.hero__search-ico {
  position: absolute; left: 1.15rem; top: 50%; transform: translateY(-50%);
  display: grid; place-items: center; color: var(--ink-dim); pointer-events: none;
}
.hero__search-input {
  flex: 1; min-width: 0;
  border: 0; background: transparent; outline: none;
  font-family: inherit; font-size: 1.02rem; color: var(--ink);
  padding-block: 0.75rem;
}
.hero__search-input::placeholder { color: var(--ink-dim); }
.hero__search-btn { flex: none; }
.hero__search-input::-webkit-search-cancel-button { cursor: pointer; }

/* popular searches — a shortcut, and a hint at what the field expects */
.hero__chips {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 0.45rem;
  margin-bottom: 2.4rem;
}
.hero__chips a {
  display: inline-block; padding: 0.35em 0.85em; border-radius: 999px;
  border: 1px solid color-mix(in oklch, white 24%, transparent);
  background: color-mix(in oklch, white 8%, transparent);
  font-family: var(--font-mono); font-size: 0.72rem; color: var(--fg-dim);
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.hero__chips a:hover, .hero__chips a:focus-visible {
  color: var(--fg); border-color: var(--accent);
  background: color-mix(in oklch, var(--accent) 20%, transparent);
}

/* ---------- category picker ----------
   Moved up to sit directly under the search, so all four cards are on screen
   without scrolling on both phone and desktop. It no longer overhangs the
   hero's bottom edge — the overlap machinery that used to pull it down is gone
   (--pick-overlap is now 0, see the top of this file). */
.hero__picker {
  position: relative; z-index: 3;
  padding-top: clamp(1.1rem, 2.2vw, 1.8rem);
}

/* Trust badges took the picker's old spot at the foot of the hero. */
.hero__trustwrap { padding-block: clamp(1.4rem, 3vw, 2.4rem) clamp(1.6rem, 3.5vw, 2.8rem); }
.pick-cards {
  display: grid; gap: 0.8rem;
  grid-template-columns: repeat(4, 1fr);
}
/* Frosted glass, deliberately LIGHT glass with dark text rather than the dark
   glass this photo would suggest. Each card straddles two backgrounds: its top
   ~80px sits on the dark hero scrim, its bottom --pick-overlap px hangs over
   the near-white section below. Dark glass with light text would be perfectly
   readable on the photo and invisible on the overhang. A light pane reads
   correctly on both, which is the whole reason for the tint sitting as high as
   62%: below roughly 55% the ink text starts failing AA against the darkest
   part of the photo. See the contrast measurements in the handover notes.

   --glass-tint is a variable so the fallbacks below can raise it in one place. */
.pick-card {
  --glass-tint: 0.66;
  /* Secondary text has to be darker ON the glass than it is on an opaque card.
     The pane composites to a mid grey (~rgb 177) over the photo, and --ink-dim
     against that measured 2.88:1 — under the 4.5:1 floor. --ink itself is fine
     at 7:1, so only the muted tones needed pulling down. Local to this card, so
     the rest of the site keeps its normal text ramp. */
  --glass-ink-dim: oklch(32% 0.014 58);

  display: flex; align-items: center; gap: 0.85rem;
  padding: 1.05rem 1.15rem;
  border-radius: var(--radius-lg, 18px);

  background: rgba(255, 255, 255, var(--glass-tint));
  /* saturate() pulls a little colour back out of the photo behind, so the pane
     reads as glass over a warm workshop scene rather than as flat grey film. */
  -webkit-backdrop-filter: blur(20px) saturate(165%);
          backdrop-filter: blur(20px) saturate(165%);

  /* Hairline edge + inner top highlight: the two things that make a translucent
     rectangle read as a physical pane instead of a washed-out box. */
  border: 1px solid rgba(255, 255, 255, 0.55);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.75),
    inset 0 -1px 0 rgba(255, 255, 255, 0.22),
    0 16px 38px oklch(18% 0.03 55 / 0.28);

  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.pick-card:hover, .pick-card:focus-visible {
  transform: translateY(-4px);
  /* Hovering frosts it up rather than lighting a border: closer to how the
     material would behave, and it lifts contrast at the same time. */
  --glass-tint: 0.76;
  border-color: color-mix(in oklch, var(--accent) 45%, rgba(255, 255, 255, 0.7));
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.85),
    inset 0 -1px 0 rgba(255, 255, 255, 0.25),
    0 22px 48px oklch(18% 0.03 55 / 0.32);
}

/* The icon chip sits ON the glass, so it is tinted rather than opaque white —
   an opaque chip on a translucent pane reads as a sticker. */
.pick-card__ico {
  flex: none; display: grid; place-items: center;
  width: 46px; height: 46px; border-radius: 13px;
  color: var(--accent-strong);
  background: color-mix(in oklch, var(--accent) 16%, rgba(255, 255, 255, 0.55));
  border: 1px solid color-mix(in oklch, var(--accent) 22%, rgba(255, 255, 255, 0.5));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
  transition: background var(--dur) var(--ease);
}
.pick-card:hover .pick-card__ico { background: color-mix(in oklch, var(--accent) 26%, rgba(255, 255, 255, 0.7)); }

/* ---- fallbacks ----
   No backdrop-filter (older Firefox with the flag off, any browser where the
   compositor refuses it): a translucent pane with no blur behind it just shows
   a sharp photo through the text, which is the one outcome worse than an opaque
   card. Go effectively solid instead — same layout, same everything, just no
   glass. Tested by forcing the query on. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pick-card {
    --glass-tint: 0.97;
    /* Near-solid surface, so the normal site text ramp reads correctly again. */
    --glass-ink-dim: var(--ink-dim);
    border-color: var(--line);
  }
  .pick-card:hover, .pick-card:focus-visible {
    --glass-tint: 1;
    border-color: color-mix(in oklch, var(--accent) 50%, var(--line));
  }
  .pick-card__ico {
    background: color-mix(in oklch, var(--accent) 12%, white);
    border-color: color-mix(in oklch, var(--accent) 18%, var(--line));
  }
}

/* Some people turn transparency off at OS level precisely because layered
   translucency is hard to read. Honour it. */
@media (prefers-reduced-transparency: reduce) {
  .pick-card {
    --glass-tint: 1;
    --glass-ink-dim: var(--ink-dim);
    -webkit-backdrop-filter: none;
            backdrop-filter: none;
    border-color: var(--line);
  }
  .pick-card__ico { background: color-mix(in oklch, var(--accent) 12%, white); }
}
.pick-card__body { flex: 1; min-width: 0; display: grid; gap: 0.1rem; }
.pick-card__body b {
  font-family: var(--font-display); font-weight: 600; font-size: 1.02rem;
  color: var(--ink); letter-spacing: -0.01em;
}
.pick-card__body small { font-size: 0.78rem; color: var(--glass-ink-dim, var(--ink-dim)); }
.pick-card__price {
  flex: none; font-family: var(--font-mono); font-size: 0.7rem;
  color: var(--glass-ink-dim, var(--ink-dim));
  text-align: right; line-height: 1.2;
}
.pick-card__price b {
  display: block; font-family: var(--font-display); font-size: 1.05rem; color: var(--ink);
}
.pick-card__go {
  flex: none; color: var(--glass-ink-dim, var(--ink-dim));
  transition: transform var(--dur) var(--ease), color var(--dur) var(--ease);
}
.pick-card:hover .pick-card__go { color: var(--accent-strong); transform: translateX(3px); }

/* ---------- kinetic marquee ---------- */
.hero__marquee {
  position: relative;
  z-index: 1;
  border-top: 1px solid color-mix(in oklch, var(--fg) 10%, transparent);
  border-bottom: 1px solid color-mix(in oklch, var(--fg) 10%, transparent);
  padding-block: 1.05rem;
  overflow: hidden;
  /* Grab and scrub. pan-y keeps a vertical swipe a page scroll, so only the
     horizontal gesture reaches the marquee; without it the browser claims the
     gesture and the strip never moves on touch. user-select stops a drag from
     selecting the brand names it passes over. */
  cursor: grab;
  touch-action: pan-y;
  -webkit-user-select: none;
          user-select: none;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.hero__marquee.is-dragging { cursor: grabbing; }
.hero__track {
  display: flex; width: max-content;
  gap: 0;
  /* The no-JS fallback only. With JS the loop is a Web Animations object
     (hero.js), which outranks this and is what pause-on-hover and dragging
     act on; the duration below is replaced there by the strip's width at
     60 px/s. Reduced motion disables both: this one further down in this
     file, the WAAPI one by never being created. */
  animation: marquee 40s linear infinite;
}
/* Items are brand logos (or a wordmark where the client supplied no logo file),
   shared with the Merken band — see inc/brand-marquee.php. A brand we carry is
   an <a class="brand-link">, one we don't is a plain <span>; both are styled
   here so the strip stays even whichever it is. */
.hero__track span,
.hero__track .brand-link {
  display: inline-flex; align-items: center;
  padding-inline: clamp(1.2rem, 2.2vw, 2.2rem);
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.1rem, 0.9rem + 1vw, 1.8rem);
  letter-spacing: -0.02em;
  color: var(--fg-dim);
  white-space: nowrap;
  transition: color var(--dur) var(--ease);
}
.hero__track span:hover,
.hero__track .brand-link:hover { color: var(--fg); }
/* the strip is interactive now, so it needs a real keyboard affordance */
.hero__track .brand-link:focus-visible {
  color: var(--fg);
  outline: 2px solid var(--accent);
  outline-offset: 4px;
  border-radius: 6px;
}
/* Muted at rest, full colour on hover/focus — the same treatment as the Merken
   band, so the two strips read as one system. */
.hero__track .brand-logo {
  display: block; height: clamp(1.75rem, 1.2rem + 1.5vw, 2.5rem); width: auto;
  filter: grayscale(1); opacity: 0.5;
  transition: filter var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.hero__track .brand-link--logo { display: flex; align-items: center; }
.hero__track .brand-link--logo:hover .brand-logo,
.hero__track .brand-link--logo:focus-visible .brand-logo { filter: none; opacity: 1; }

/* ---------- keyframes ---------- */
/* Slow push on the background photo. Transform only, so it stays on the
   compositor and never triggers layout. */
@keyframes heroPan {
  from { transform: scale(1.04) translate3d(0, 0, 0); }
  to   { transform: scale(1.12) translate3d(-1.5%, -1.5%, 0); }
}
@keyframes marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
@keyframes badgePulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in oklch, var(--accent-ink) 55%, transparent); }
  70%  { box-shadow: 0 0 0 8px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* ---------- responsive ---------- */
@media (max-width: 960px) {
  .pick-cards { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 720px) {
  .hero__center { padding-block: clamp(2rem, 6vh, 3.5rem) 2rem; }
  /* One pill, not a stacked box. The old treatment wrapped the field and put a
     full-width button underneath, which broke the pill shape, read as a form
     rather than a search, and cost ~57px of the fold. Now the submit collapses
     to a round accent button sitting inside the pill on the right — the shape
     survives, the magnifier still marks the left, and the whole control is one
     object. */
  .hero__search {
    flex-wrap: nowrap;
    border-radius: 999px;
    padding: 0.32rem 0.32rem 0.32rem 2.75rem;
    gap: 0.4rem;
  }
  .hero__search-ico { left: 1rem; top: 50%; transform: translateY(-50%); }
  .hero__search-input {
    flex: 1; min-width: 0;
    padding-block: 0.6rem;
    font-size: 0.95rem;
  }
  .hero__search-btn {
    flex: none;
    width: 44px; height: 44px; padding: 0;
    justify-content: center; border-radius: 50%;
  }
  .hero__search-btn-label { display: none; }
  .hero__search-btn .btn-arrow { width: 17px; height: 17px; }
  .hero__trust { justify-content: center; }
}
/* On a phone the four cards have to share the first screen with the headline
   and the search, and four stacked full-width rows (~390px) simply do not fit
   above the fold. A 2x2 of compact tiles is ~180px and does — same four
   destinations, a third of the height. */
@media (max-width: 620px) {
  .pick-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.55rem; }
  .pick-card {
    flex-direction: column; align-items: flex-start; gap: 0.5rem;
    padding: 0.85rem 0.9rem;
  }
  .pick-card__ico { width: 38px; height: 38px; border-radius: 11px; }
  .pick-card__ico svg { width: 21px; height: 21px; }
  .pick-card__body b { font-size: 0.95rem; }
  /* Description, price and arrow are all secondary to "which device is it" —
     they are the first things to go when the tile shrinks. */
  .pick-card__body small,
  .pick-card__price,
  .pick-card__go { display: none; }

  /* The chips are back, but as ONE swipeable row instead of a wrapping block.
     Wrapping cost ~110px of the fold; a single scrolling line costs ~34px and
     keeps every shortcut reachable. */
  .hero__chips {
    display: flex; flex-wrap: nowrap; justify-content: flex-start;
    gap: 0.4rem; margin-bottom: 0;
    overflow-x: auto; scrollbar-width: none;
    /* bleed to the screen edges so the row reads as scrollable */
    margin-inline: calc(var(--gutter) * -1);
    padding-inline: var(--gutter);
    scroll-snap-type: x proximity;
  }
  .hero__chips::-webkit-scrollbar { display: none; }
  .hero__chips li { flex: none; scroll-snap-align: start; }

  /* The subtitle is the biggest single block above the cards and repeats what
     the headline already says. Desktop keeps it; on a phone the cards matter
     more than the prose. */
  .hero__sub { display: none; }

  /* Tightened to land both rows of tiles above the fold on a 375x812 phone. */
  .hero__center { padding-block: 1.1rem 0.9rem; }
  .hero__title { margin-bottom: 0.85rem; }
  .hero__picker { padding-top: 0.85rem; }

  .hero__trust { gap: 1.2rem 1.6rem; }
  .hero__trust-item .num { font-size: 1.25rem; }
}

/* reduced motion: kill drift, marquee, reveal — show final state */
@media (prefers-reduced-motion: reduce) {
  .hero__media img, .hero__track { animation: none !important; }
  .hero__track .brand-logo, .hero__track .brand-link { transition: none !important; }
  .hero__title .line > span { transform: none !important; transition: none !important; }
  .hero__title .accent::after { transform: scaleX(1) !important; transition: none !important; }
  .hero__search, .pick-card { transition: none !important; }
  .pick-card:hover { transform: none !important; }
}
