/* ULGO — Colour PPF, PPF and MGC coating landing page.
   =========================================================================
   The palette is taken from the client's own mark, which is white on black
   and nothing else. So the page is monochrome and EVERY colour on it comes
   out of a photograph of a car. That is the whole idea: the colour swatch
   row in the hero is then the only place colour changes, which is exactly
   what the product does.

   Deliberately not the Stelix institutional navy/gold. This is a premium
   automotive workshop, not a consumer authority.
   ========================================================================= */

:root {
  --ink: #08080a;
  --ink-2: #101014;
  --ink-3: #17171c;
  --line: #26262e;
  --paper: #f6f6f7;
  --mute: #8d8d98;
  --mute-2: #5f5f6b;

  --display: "Outfit", "Segoe UI", system-ui, sans-serif;
  --body: "Instrument Sans", "Segoe UI", system-ui, sans-serif;

  --gut: clamp(20px, 5vw, 76px);
  --max: 1320px;
  --rule: 1px solid var(--line);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  /* overflow-x: clip, never hidden: hidden kills every position:sticky
     ancestor chain on the page. */
  overflow-x: clip;
}
/* height:auto is NOT optional here. Every <img> carries width/height
   attributes for layout stability, and without this the attribute height
   is treated as the specified height: max-width scales the width, the
   height stays pinned at 1350, and a 4:3 photograph renders as a 0.41
   ratio smear. It also tripled the page height, which pushed the gallery
   so far down that its lazy images never entered the viewport at all. */
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }

.wrap { width: 100%; max-width: var(--max); margin: 0 auto; padding: 0 var(--gut); }

/* ---------- type ------------------------------------------------------- */
/* The hero eyebrow needs 469px and its column is 460px at 1440 and 353px at
   1000, so it wraps no matter what the letter-spacing is. Binding each phrase
   means the break lands on a separator instead of orphaning the single word
   "COATING" on its own line under the first line of the page. */
.eyebrow .nb { white-space: nowrap; }

.eyebrow {
  font-family: var(--body);
  font-size: 13px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--mute);
  margin: 0 0 18px;
}
h1, h2, h3 { font-family: var(--display); font-weight: 200; margin: 0; }
h1 {
  font-size: clamp(42px, 7.4vw, 92px);
  line-height: .98;
  letter-spacing: -.025em;
}
h2 {
  font-size: clamp(30px, 4.4vw, 54px);
  line-height: 1.05;
  letter-spacing: -.02em;
}
h3 { font-size: clamp(19px, 2vw, 23px); font-weight: 600; letter-spacing: -.01em; }
h1 b, h2 b { font-weight: 600; }
p { margin: 0 0 1em; color: #d3d3da; }
p.lead { font-size: clamp(18px, 1.9vw, 21px); color: #e2e2e8; max-width: 56ch; }
.small { font-size: 15px; color: var(--mute); }

/* ---------- header ----------------------------------------------------- */
.hdr {
  position: sticky; top: 0; z-index: 60;
  background: rgba(8, 8, 10, .78);
  backdrop-filter: blur(14px);
  border-bottom: var(--rule);
}
.hdr__in { display: flex; align-items: center; gap: 28px; height: 74px; }
.hdr__logo img { height: 26px; width: auto; }
.hdr nav { margin-left: auto; display: flex; gap: 28px; }
.hdr nav a {
  text-decoration: none; font-size: 14px; letter-spacing: .04em;
  color: var(--mute); transition: color .2s;
}
.hdr nav a:hover { color: var(--paper); }
@media (max-width: 860px) { .hdr nav { display: none; } .hdr__in { gap: 14px; } }

.btn {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 13px 22px; border-radius: 999px;
  font-size: 15px; font-weight: 500; letter-spacing: .01em;
  text-decoration: none; border: 1px solid transparent;
  transition: transform .18s, background .18s, border-color .18s;
}
.btn:hover { transform: translateY(-1px); }
.btn--solid { background: var(--paper); color: var(--ink); }
.btn--solid:hover { background: #fff; }
.btn--line { border-color: #3a3a45; color: var(--paper); }
.btn--line:hover { border-color: var(--paper); }
.hdr .btn { margin-left: auto; padding: 10px 18px; font-size: 14px; }
@media (min-width: 861px) { .hdr .btn { margin-left: 0; } }

/* ---------- hero: the colour switcher ---------------------------------- */
.hero { padding: clamp(46px, 7vw, 96px) 0 0; }
.hero__grid {
  display: grid; gap: clamp(26px, 4vw, 54px);
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 1000px) {
  .hero__grid { grid-template-columns: minmax(340px, 0.82fr) minmax(0, 1.18fr); align-items: end; }
}
.hero h1 { margin-bottom: 22px; }
.hero__note { color: var(--mute); font-size: 15px; max-width: 34ch; }

.stage {
  position: relative; border-radius: 14px; overflow: hidden;
  background: var(--ink-2) center/cover no-repeat;
  aspect-ratio: 4 / 3;
}
.stage img {
  width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity .42s ease;
}
.stage img.is-on { opacity: 1; }
.stage__tag {
  position: absolute; left: 16px; bottom: 16px; z-index: 3;
  display: inline-flex; align-items: center; gap: 9px;
  padding: 9px 15px; border-radius: 999px;
  background: rgba(8, 8, 10, .62); backdrop-filter: blur(8px);
  font-size: 13px; letter-spacing: .05em; text-transform: uppercase;
}
.stage__tag i { width: 11px; height: 11px; border-radius: 50%; display: block; }

.swatches {
  display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px;
}
.sw {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 9px 16px 9px 10px; border-radius: 999px;
  background: var(--ink-2); border: 1px solid var(--line);
  color: var(--mute); font-family: var(--body); font-size: 14px;
  cursor: pointer; transition: border-color .2s, color .2s, background .2s;
}
.sw i {
  width: 18px; height: 18px; border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .22);
}
.sw:hover { color: var(--paper); border-color: #3c3c47; }
.sw[aria-pressed="true"] { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.sw[aria-pressed="true"] i { box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .3); }

/* ---------- proof strip ------------------------------------------------ */
.proof { margin-top: clamp(40px, 6vw, 78px); border-top: var(--rule); border-bottom: var(--rule); }
.proof__in { display: grid; grid-template-columns: repeat(2, 1fr); }
@media (min-width: 760px) { .proof__in { grid-template-columns: repeat(4, 1fr); } }
.proof__cell { padding: 26px 0; border-left: var(--rule); padding-left: 22px; }
.proof__cell:first-child { border-left: 0; padding-left: 0; }
@media (max-width: 759px) {
  .proof__cell:nth-child(3) { border-left: 0; padding-left: 0; }
  .proof__cell:nth-child(-n+2) { border-bottom: var(--rule); }
}
.proof__n { font-family: var(--display); font-size: clamp(26px, 3vw, 34px); font-weight: 200; }
.proof__l { font-size: 13px; color: var(--mute); letter-spacing: .06em; text-transform: uppercase; }

/* ---------- generic section ------------------------------------------- */
section { padding: clamp(58px, 9vw, 122px) 0; }
.sechead { max-width: 60ch; margin-bottom: clamp(30px, 4vw, 52px); }

/* split row: image one side, words the other, alternating */
.split { display: grid; gap: clamp(26px, 4vw, 60px); align-items: center; }
@media (min-width: 940px) {
  .split { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .split--flip > *:first-child { order: 2; }
}
/* Give the figure a shape of its own and let the photograph fill it. Left to
   its natural height a 4:3 frame sat well short of the spec list beside it and
   the row read as mostly empty dark. The whole point of this client is that
   they have real photographs, so the photographs get the room. */
.split figure {
  margin: 0; border-radius: 12px; overflow: hidden;
  background: var(--ink-2); aspect-ratio: 4 / 3;
}
.split figure img { width: 100%; height: 100%; object-fit: cover; }
@media (min-width: 940px) { .split figure { aspect-ratio: 5 / 4; } }

/* specification block: a tight data list, not a row of identical cards */
.specs { border-top: var(--rule); margin-top: 8px; }
.spec {
  display: grid; grid-template-columns: 54px 1fr; gap: 18px;
  padding: 18px 0; border-bottom: var(--rule); align-items: baseline;
}
.spec__n { font-family: var(--display); font-size: 14px; color: var(--mute-2); letter-spacing: .1em; }
.spec__t { font-weight: 500; }
.spec__d { color: var(--mute); font-size: 15px; margin: 4px 0 0; }

/* full-bleed band */
.band { position: relative; padding: 0; }
.band img { width: 100%; height: clamp(300px, 52vh, 560px); object-fit: cover; }
.band__cap {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 26px var(--gut);
  background: linear-gradient(to top, rgba(8, 8, 10, .82), transparent);
  font-size: 14px; color: #cfcfd8;
}

/* the work: deliberately uneven, so it does not read as a stock card grid */
.work { display: grid; gap: 12px; grid-template-columns: repeat(2, 1fr); }
@media (min-width: 900px) { .work { grid-template-columns: repeat(6, 1fr); } }
.work figure { margin: 0; border-radius: 10px; overflow: hidden; background: var(--ink-2); }
.work img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 4 / 3; }
@media (min-width: 900px) {
  .work figure:nth-child(1) { grid-column: span 4; }
  .work figure:nth-child(1) img { aspect-ratio: 16 / 9; }
  .work figure:nth-child(2) { grid-column: span 2; }
  .work figure:nth-child(2) img { aspect-ratio: 4 / 5; }
  .work figure:nth-child(3),
  .work figure:nth-child(4) { grid-column: span 2; }
  .work figure:nth-child(5) { grid-column: span 2; }
  .work figure:nth-child(6) { grid-column: span 3; }
  .work figure:nth-child(7) { grid-column: span 3; }
}

/* ---------- studios + cta ---------------------------------------------- */
.studios { display: grid; gap: 26px; }
@media (min-width: 820px) { .studios { grid-template-columns: repeat(2, 1fr); } }
.studio { border: var(--rule); border-radius: 12px; padding: 28px; background: var(--ink-2); }
.studio h3 { margin-bottom: 8px; }
.studio address { font-style: normal; color: var(--mute); font-size: 15px; line-height: 1.6; }

.cta { border-top: var(--rule); }
.cta__in { display: grid; gap: 28px; align-items: center; }
@media (min-width: 900px) { .cta__in { grid-template-columns: 1.3fr 1fr; } }
.cta__btns { display: flex; flex-wrap: wrap; gap: 12px; }

/* ---------- enquiry form ----------------------------------------------- */
/* The page is monochrome, so a field cannot be tinted to show focus or an
   error. Both states are carried by the BORDER, which is the only surface a
   dark form has left. */
.form {
  border: var(--rule); border-radius: 14px;
  padding: clamp(22px, 3vw, 30px);
  background: var(--ink-2);
  display: grid; gap: 14px;
}
.form__title {
  margin: 0 0 2px; font-size: 14px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--mute);
}
.f { display: grid; gap: 6px; }
.f2 { display: grid; gap: 14px; }
@media (min-width: 480px) { .f2 { grid-template-columns: 1fr 1fr; } }
.f label { font-size: 14px; color: var(--mute); }
.f .opt { color: var(--mute-2); }
.f input, .f select {
  width: 100%;
  /* 16px is not a taste decision: iOS Safari zooms the whole page on focus
     for anything smaller, and the zoom does not come back. */
  font: 400 16px/1.4 var(--body);
  color: var(--paper);
  background: var(--ink-3);
  border: 1px solid var(--line);
  border-radius: 9px;
  padding: 12px 13px;
  transition: border-color .16s;
  /* a dark native select renders its arrow black-on-black on Windows */
  appearance: none; -webkit-appearance: none;
}
.f select {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%238d8d98' stroke-width='1.6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-right: 38px;
}
.f select:invalid { color: var(--mute-2); }
.f input:focus-visible, .f select:focus-visible {
  outline: none; border-color: var(--paper);
}
.f input[aria-invalid="true"], .f select[aria-invalid="true"] { border-color: #d2564d; }
.form__go { justify-content: center; margin-top: 4px; cursor: pointer; }
.form__go[disabled] { opacity: .55; cursor: default; }
.form__msg { margin: 0; font-size: 14px; min-height: 1.4em; color: var(--mute); }
.form__msg[data-state="err"] { color: #e0796f; }
.form__msg[data-state="ok"] { color: var(--paper); }
/* Clipped rather than display:none — a bot that skips hidden inputs would
   never fall in, and this has to look fillable to it. Clipped rather than
   left:-9999px too: an element parked off-canvas is indistinguishable from a
   real horizontal-overflow bug to any viewport audit, including our own, and
   a decoy is not worth a permanently noisy check. */
.hp { height: 0; overflow: hidden; }

/* ---------- footer ----------------------------------------------------- */
footer { border-top: var(--rule); padding: 36px 0 54px; color: var(--mute); font-size: 14px; }
.foot__in { display: flex; flex-wrap: wrap; gap: 18px 34px; align-items: center; }
footer img { height: 22px; opacity: .8; }
footer a { color: var(--mute); }
footer a:hover { color: var(--paper); }

/* ---------- reveal ----------------------------------------------------- */
/* Content is visible by DEFAULT. The hidden state only exists once the inline
   script in <head> has put .js on <html>, so if the script never runs, the
   stylesheet 404s halfway, or the observer throws, the page is still a page.
   The first build hid everything below the hero because the observer had not
   fired yet, and a full-page screenshot showed a black column. That was a
   screenshot artefact AND a real failure mode. */
.js [data-rev] { opacity: 0; transform: translateY(16px); transition: opacity .7s ease, transform .7s ease; }
.js [data-rev].is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js [data-rev] { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
  .stage img { transition: none; }
}

/* sticky WhatsApp on phones only, where the thumb is */
.wa-fix {
  position: fixed; right: 16px; bottom: 16px; z-index: 70;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .5);
  transition: opacity .2s, transform .2s;
}
@media (min-width: 861px) { .wa-fix { display: none; } }
/* It sat directly on top of the Car brand field on a 390px screen, so a tap
   near that edge opened WhatsApp instead of focusing the input. It is also
   redundant there: the enquiry section already carries its own WhatsApp
   button. Set by IntersectionObserver, so with JS off nothing changes and the
   button simply stays. */
body.at-enquire .wa-fix {
  opacity: 0; pointer-events: none; transform: translateY(10px);
}
