/* ============================================================
   NQA DETAILS — CORE THEME  ·  "BLACK & BURGUNDY"
   ------------------------------------------------------------
   Single source of truth for palette + shared primitives.
   Loaded FIRST by every page, before the page-specific sheet:
     index / gallery / services / areas → css/style.css
     contact                            → css/lander.css
     booking                            → css/booking.css

   The brand mark is metallic burgundy and chrome on pure black,
   so the whole site lives in the dark. The duotone here is two
   depths of black rather than light-vs-dark: OBSIDIAN bands
   (near-black, the floor) and CARBON bands (lifted charcoal).
   Sections opt in with .tone-dark or .tone-light — those classes
   REDEFINE the ink/surface/line tokens locally, so every
   component adapts automatically with no duplicated rules.

   Change a brand colour HERE and it moves everywhere.
   ============================================================ */

:root {
  /* ---- grounds ---- */
  --void:       #060608;   /* footer floor / deepest           */
  --obsidian:   #0a0a0d;   /* dark band                        */
  --obsidian-2: #0e0e12;   /* dark band, raised                */
  --carbon:     #131318;   /* light band (lifted charcoal)     */
  --carbon-2:   #191920;   /* light band, deeper               */
  --slate:      #1e1e26;   /* card surface                     */
  --slate-2:    #26262f;   /* card surface, hover              */

  /* ---- brand (immutable — never re-scoped by a tone) ----
     Sampled from the logo: the deep burgundy of the NQA letterforms,
     the brighter crimson of their bevel highlight, and the brushed
     chrome of the "details" script. */
  --brand:       #9e1b2b;  /* core burgundy                    */
  --brand-lift:  #c8323f;  /* legible burgundy for dark grounds*/
  --brand-bright:#e0505c;  /* highlight / hover peak           */
  --brand-deep:  #66101c;  /* shadow side of the bevel         */
  --brand-tint:  rgba(200, 50, 63, .13);
  --brand-glass: rgba(200, 50, 63, .08);
  --brand-line:  rgba(200, 50, 63, .30);

  --chrome:      #c9ccd3;  /* brushed silver — the second accent */
  --chrome-soft: #eceef2;
  --chrome-deep: #8d919b;
  --chrome-ink:  #0c0c10;  /* text ON a chrome fill            */

  --danger:      #e0505c;
  --ok:          #3fbf7f;

  /* ---- semantic tokens (CARBON default — .tone-dark deepens them) ---- */
  --band:      var(--carbon);
  --surface:   var(--slate);
  --surface-2: var(--slate-2);
  --ink:       #f4f5f8;
  --ink-soft:  #b3b7c0;
  --muted:     #7c818c;
  --line:      rgba(255, 255, 255, .09);
  --line-2:    rgba(255, 255, 255, .17);
  --field-bg:  rgba(255, 255, 255, .045);

  /* ---- geometry ---- */
  --radius:     18px;
  --radius-sm:  12px;
  --radius-btn: 10px;
  --wrap:       1180px;

  /* ---- elevation ---- */
  --shadow:    0 2px 4px rgba(0, 0, 0, .4), 0 12px 30px rgba(0, 0, 0, .42);
  --shadow-md: 0 4px 10px rgba(0, 0, 0, .45), 0 22px 52px rgba(0, 0, 0, .5);
  --shadow-lg: 0 10px 20px rgba(0, 0, 0, .5), 0 40px 90px rgba(0, 0, 0, .65);

  /* ---- type ----
     Oswald echoes the condensed headings on the client's flyer; Inter
     carries everything else. The script in the logo is left to the logo —
     pulling in a third webfont for one decorative word isn't worth the
     request on a site whose traffic is mostly phones. */
  --fd: "Oswald", "Barlow Condensed", "Arial Narrow", sans-serif;
  --fb: "Inter", "Helvetica Neue", Arial, sans-serif;
  --font-display: var(--fd);
  --font-body: var(--fb);

  --ease: cubic-bezier(.22, 1, .36, 1);

  /* ---- texture: fine grain so the flat blacks don't band ---- */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.42'/%3E%3C/svg%3E");
}

/* ============================================================
   TONE SCOPES — the heart of the duotone system
   ============================================================ */
.tone-dark {
  --band:      var(--obsidian);
  --surface:   rgba(255, 255, 255, .045);
  --surface-2: rgba(255, 255, 255, .075);
  --ink:       #f6f7f9;
  --ink-soft:  #aeb2bb;
  --muted:     #767b86;
  --line:      rgba(255, 255, 255, .08);
  --line-2:    rgba(255, 255, 255, .16);
  --field-bg:  rgba(255, 255, 255, .04);

  background-color: var(--obsidian);
  background-image: var(--grain);
  background-blend-mode: overlay;
  color: var(--ink-soft);
}
.tone-light {
  background-color: var(--carbon);
  background-image: var(--grain);
  background-blend-mode: overlay;
  color: var(--ink-soft);
}
.tone-pearl { background: var(--carbon-2); color: var(--ink-soft); }
.tone-white { background: var(--slate); color: var(--ink-soft); }

/* a burgundy hairline where two bands meet */
.tone-dark + .tone-light,
.tone-light + .tone-dark,
.tone-dark + .tone-pearl,
.tone-light + .tone-pearl {
  border-top: 1px solid rgba(200, 50, 63, .16);
}

/* ============================================================
   RESET / BASE
   ============================================================ */
* { margin: 0; padding: 0; box-sizing: border-box; }
*::selection { background: rgba(200, 50, 63, .34); color: #fff; }
[hidden] { display: none !important; }

html { scroll-behavior: smooth; scroll-padding-top: 90px; }

body {
  background: var(--obsidian);
  color: var(--ink-soft);
  font-family: var(--fb);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }

:focus-visible {
  outline: 2px solid var(--brand-lift);
  outline-offset: 3px;
  border-radius: 4px;
}

.container, .wrap { width: min(var(--wrap), 92%); margin-inline: auto; }

/* announced to screen readers, invisible on screen */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ============================================================
   TYPOGRAPHY
   ============================================================ */
.display, h1, h2, h3, h4 {
  font-family: var(--fd);
  font-weight: 600;
  text-transform: uppercase;
  color: var(--ink);
  line-height: 1.02;
  letter-spacing: .012em;
  text-wrap: balance;
}
h1 { font-size: clamp(2.7rem, 6.6vw, 5rem); font-weight: 700; line-height: .98; }
h2 { font-size: clamp(2rem, 4.4vw, 3.4rem); font-weight: 600; }
h3 { font-size: clamp(1.35rem, 2.4vw, 1.85rem); }
h4 { font-size: 1.16rem; }
p  { color: var(--ink-soft); }

.accent { color: var(--brand-lift); }
/* headline accents get the metallic bevel of the logo letterforms */
h1 .accent, h2 .accent {
  background: linear-gradient(96deg, var(--brand) 6%, var(--brand-bright) 34%, #ffd9dd 50%, var(--brand-bright) 66%, var(--brand) 96%);
  background-size: 260% 100%;
  background-position: 50% 0;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
h1 .accent-chrome, h2 .accent-chrome {
  background: linear-gradient(96deg, var(--chrome-deep) 6%, #ffffff 44%, var(--chrome) 62%, var(--chrome-deep) 96%);
  background-size: 260% 100%;
  background-position: 50% 0;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
/* …and the sheen travels across the word once, as the heading arrives */
.reveal.visible h2 .accent,
.reveal.visible h2 .accent-chrome,
.hero h1 .accent,
.hero h1 .accent-chrome,
.page-hero h1 .accent,
.page-hero h1 .accent-chrome {
  animation: chrome-sweep 1.8s var(--ease) .2s both;
}
@keyframes chrome-sweep {
  from { background-position: 138% 0; }
  to   { background-position: 20% 0; }
}

.lead { font-size: 1.09rem; color: var(--ink-soft); max-width: 58ch; }
.dim  { color: var(--muted); }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  font-family: var(--fb);
  font-style: normal;
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--brand-lift);
}
.eyebrow::before {
  content: "";
  width: 32px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--brand-lift));
}

/* price treatments */
.was {
  text-decoration: line-through;
  text-decoration-thickness: 2px;
  color: var(--muted);
  font-weight: 400;
  margin-right: 6px;
}
.save-tag {
  display: inline-block;
  background: linear-gradient(180deg, var(--chrome-soft), var(--chrome-deep));
  color: var(--chrome-ink);
  font-family: var(--fb);
  font-size: .66rem;
  font-weight: 800;
  letter-spacing: .13em;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: 999px;
  vertical-align: middle;
  margin-left: 8px;
  box-shadow: 0 3px 12px rgba(0, 0, 0, .5);
}
.save-inline { color: var(--chrome); font-weight: 700; font-size: .85em; }

.offer-pill {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  background: rgba(200, 50, 63, .12);
  border: 1px solid var(--brand-line);
  color: #f0b8bd;
  font-weight: 700;
  font-size: .78rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  padding: 9px 19px;
  border-radius: 999px;
}
.offer-pill::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--brand-lift);
  box-shadow: 0 0 0 4px rgba(200, 50, 63, .2);
  animation: live-dot 2.4s ease-in-out infinite;
}
@keyframes live-dot {
  50% { box-shadow: 0 0 0 8px rgba(200, 50, 63, 0); }
}

/* ============================================================
   BUTTONS
   ============================================================ */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 15px 32px;
  border-radius: var(--radius-btn);
  font-family: var(--fb);
  font-weight: 700;
  font-size: .86rem;
  letter-spacing: .11em;
  text-transform: uppercase;
  border: 1.5px solid transparent;
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  white-space: nowrap;
  transition: transform .25s var(--ease), box-shadow .25s var(--ease),
              background .2s ease, color .2s ease, border-color .2s ease;
}
.btn svg { width: 18px; height: 18px; fill: currentColor; }

/* light sweep that crosses the button on hover */
.btn::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 38%, rgba(255, 255, 255, .3) 50%, transparent 62%);
  transform: translateX(-120%);
  transition: transform .65s var(--ease);
  pointer-events: none;
  z-index: 1;
}
.btn:hover::after { transform: translateX(120%); }

.btn-primary {
  background: linear-gradient(180deg, var(--brand-lift), var(--brand) 55%, var(--brand-deep));
  color: #fff;
  border-color: rgba(255, 255, 255, .12);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .2) inset, 0 10px 28px rgba(158, 27, 43, .45);
}
.btn-primary:hover {
  background: linear-gradient(180deg, var(--brand-bright), var(--brand-lift) 55%, var(--brand));
  transform: translateY(-3px);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .24) inset, 0 16px 40px rgba(200, 50, 63, .55);
}
.btn-chrome {
  background: linear-gradient(180deg, #ffffff, var(--chrome) 52%, var(--chrome-deep));
  color: var(--chrome-ink);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .6) inset, 0 10px 28px rgba(0, 0, 0, .55);
}
.btn-chrome:hover {
  background: linear-gradient(180deg, #ffffff, var(--chrome-soft) 52%, var(--chrome));
  transform: translateY(-3px);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .7) inset, 0 16px 40px rgba(0, 0, 0, .6);
}
.btn-ghost, .btn-outline {
  background: transparent;
  color: var(--ink);
  border-color: var(--line-2);
}
.btn-ghost:hover, .btn-outline:hover {
  border-color: var(--brand-lift);
  color: #fff;
  background: rgba(200, 50, 63, .14);
  transform: translateY(-3px);
}

.btn-sm { padding: 11px 22px; font-size: .74rem; }
.btn-lg { padding: 17px 38px; font-size: .93rem; }
.btn-block { width: 100%; }
.btn:active { transform: translateY(-1px) scale(.99); }

.btn-row {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: 42px;
  text-align: center;
}

/* ============================================================
   CARD PRIMITIVE  (+ cursor spotlight, driven by main.js)
   ============================================================ */
.card, .surface {
  position: relative;
  background: linear-gradient(168deg, rgba(255, 255, 255, .06), rgba(255, 255, 255, .018));
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease), border-color .35s ease;
}
.card:hover, .surface:hover {
  transform: translateY(-7px);
  box-shadow: var(--shadow-md);
  border-color: var(--brand-line);
}

/* spotlight: main.js writes --mx/--my as the pointer moves */
.spot::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(360px circle at var(--mx, 50%) var(--my, 0%),
              rgba(200, 50, 63, .17), transparent 62%);
  opacity: 0;
  transition: opacity .35s ease;
  pointer-events: none;
  z-index: 0;
}
.spot:hover::before { opacity: 1; }
.spot > * { position: relative; z-index: 1; }

/* ============================================================
   SCROLL PROGRESS RAIL (injected by main.js)
   ============================================================ */
.scroll-prog {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 3px;
  z-index: 200;
  background: transparent;
  pointer-events: none;
}
.scroll-prog span {
  display: block;
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--brand-deep), var(--brand-lift) 55%, var(--chrome));
  box-shadow: 0 0 12px rgba(200, 50, 63, .7);
  transition: width .1s linear;
}

/* ============================================================
   TOP INFO STRIP (ticker)
   ============================================================ */
.deal-strip {
  position: relative;
  background: linear-gradient(90deg, var(--brand-deep) 0%, var(--brand) 48%, var(--brand-deep) 100%);
  color: #ffe9eb;
  text-align: center;
  padding: 10px 0;
  font-weight: 700;
  font-size: .77rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  line-height: 1.3;
  overflow: hidden;
}
.deal-strip strong { color: #fff; }

/* ---------- ticker ----------
   main.js wraps the strip's contents in .ds-track and duplicates the
   set exactly once, so translating the track by -50% lands on an
   identical frame and the loop is seamless. Speed is set from the
   measured width (constant px/sec), so a long strip doesn't crawl. */
.deal-strip.is-ticker { padding-inline: 0; }
.deal-strip .ds-track {
  display: flex;
  width: max-content;
  will-change: transform;
  animation: ds-scroll var(--ds-dur, 34s) linear infinite;
}
.deal-strip .ds-item {
  flex-shrink: 0;
  padding-right: 3.5rem;
  white-space: nowrap;
}
/* soft fade at both ends so text doesn't hard-clip at the edges */
.deal-strip.is-ticker::before,
.deal-strip.is-ticker::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  width: 46px;
  z-index: 2;
  pointer-events: none;
}
.deal-strip.is-ticker::before { left: 0;  background: linear-gradient(90deg, var(--brand-deep), transparent); }
.deal-strip.is-ticker::after  { right: 0; background: linear-gradient(270deg, var(--brand-deep), transparent); }

@keyframes ds-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
/* let people stop it to actually read it */
.deal-strip:hover .ds-track { animation-play-state: paused; }

@media (max-width: 520px) {
  .deal-strip { font-size: .7rem; padding: 9px 0; }
  .deal-strip .ds-item { padding-right: 2.5rem; }
  .deal-strip.is-ticker::before, .deal-strip.is-ticker::after { width: 28px; }
}
@media (prefers-reduced-motion: reduce) {
  .deal-strip .ds-track { animation: none; }
}

/* ============================================================
   TOP UTILITY BAR
   ============================================================ */
/* One slim line, never wrapping. Below 900px it drops out entirely —
   the phone already lives in the nav button and the sticky bar. */
.topbar {
  background: var(--void);
  color: #8a8f99;
  font-size: .74rem;
  letter-spacing: .04em;
  border-bottom: 1px solid rgba(255, 255, 255, .05);
}
.topbar .container, .topbar .wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0 16px;
  flex-wrap: nowrap;
  padding: 7px 0;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
}
.topbar .container > span, .topbar .wrap > span { flex-shrink: 0; }
@media (max-width: 1100px) {
  .topbar .container > span:nth-child(3),
  .topbar .wrap > span:nth-child(3),
  .topbar .container > span:nth-child(4),
  .topbar .wrap > span:nth-child(4) { display: none; }
}
@media (max-width: 900px) { .topbar { display: none; } }
.topbar b { color: #fff; font-weight: 700; }
.topbar a {
  color: #fff;
  font-weight: 700;
  border-bottom: 1px solid rgba(255, 255, 255, .26);
  transition: border-color .2s ease, color .2s ease;
}
.topbar a:hover { color: var(--brand-bright); border-color: var(--brand-bright); }
.topbar .tb-dot { color: var(--brand); opacity: .8; }

/* ============================================================
   NAV — glass rail, condenses on scroll
   ============================================================ */
.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(10, 10, 13, .78);
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  border-bottom: 1px solid rgba(255, 255, 255, .07);
  transition: box-shadow .3s ease, background .3s ease, border-color .3s ease;
}
.nav.scrolled {
  background: rgba(8, 8, 11, .95);
  box-shadow: 0 10px 34px rgba(0, 0, 0, .6);
  border-bottom-color: rgba(200, 50, 63, .22);
}
.nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 11px 0;
  transition: padding .3s var(--ease);
}
.nav.scrolled .nav-inner { padding: 6px 0; }

.nav-brand { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
/* The mark is a full lockup (shield + wordmark), so it needs real height
   before "NQAdetails" is legible at all. */
.nav-brand img {
  height: 68px;
  width: auto;
  transition: height .3s var(--ease), filter .3s ease;
  filter: drop-shadow(0 4px 14px rgba(200, 50, 63, .35));
}
.nav.scrolled .nav-brand img { height: 54px; }
.nav-brand .brand-name {
  font-family: var(--fb);
  font-weight: 600;
  text-transform: uppercase;
  color: var(--chrome);
  font-size: .68rem;
  line-height: 1.35;
  letter-spacing: .26em;
  max-width: 120px;
}

.nav-links { display: flex; align-items: center; gap: 26px; list-style: none; }
.nav-links a {
  white-space: nowrap;
  font-size: .74rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding: 7px 0;
  position: relative;
  transition: color .2s ease;
}
.nav-links a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 0; height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--brand), var(--brand-bright));
  transition: width .3s var(--ease);
}
.nav-links a:hover, .nav-links a.active { color: #fff; }
.nav-links a:hover::after, .nav-links a.active::after { width: 100%; }
.nav-links .mobile-only { display: none; }

.nav-phone {
  flex-shrink: 0;
  width: 46px; height: 46px;
  border-radius: 13px;
  background: rgba(200, 50, 63, .13);
  border: 1px solid var(--brand-line);
  display: grid;
  place-items: center;
  transition: transform .25s var(--ease), background .25s ease, box-shadow .25s ease;
}
.nav-phone:hover {
  transform: translateY(-3px);
  background: var(--brand);
  box-shadow: 0 10px 26px rgba(158, 27, 43, .55);
}
.nav-phone svg { width: 22px; height: 22px; fill: var(--brand-bright); transition: fill .2s ease; }
.nav-phone:hover svg { fill: #fff; }
.nav-cta { flex-shrink: 0; }

.nav-toggle {
  display: none;
  background: rgba(255, 255, 255, .05);
  border: 1px solid var(--line-2);
  border-radius: 11px;
  padding: 10px 11px;
  cursor: pointer;
  transition: border-color .2s ease;
}
.nav-toggle:hover { border-color: var(--brand-lift); }
.nav-toggle span {
  display: block;
  width: 22px; height: 2px;
  border-radius: 2px;
  background: var(--ink);
  margin: 5px 0;
  transition: transform .3s var(--ease), opacity .2s ease;
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ============================================================
   FORM FIELDS
   ============================================================ */
.field { margin-bottom: 13px; }
.field label {
  display: block;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 7px;
}
.field label .opt { font-weight: 500; letter-spacing: .02em; text-transform: none; }
.field input, .field select, .field textarea {
  width: 100%;
  background: var(--field-bg);
  border: 1.5px solid var(--line-2);
  border-radius: var(--radius-sm);
  color: var(--ink);
  font-family: var(--fb);
  font-size: 1rem;
  padding: 14px 15px;
  transition: border-color .2s ease, box-shadow .2s ease, background .2s ease;
}
.field input::placeholder, .field textarea::placeholder { color: #6a6f79; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  background: rgba(255, 255, 255, .07);
  border-color: var(--brand-lift);
  box-shadow: 0 0 0 4px rgba(200, 50, 63, .16);
}
.field select {
  appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--muted) 50%),
    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 20px) 55%, calc(100% - 14px) 55%;
  background-size: 6px 6px;
  background-repeat: no-repeat;
}
.field select option { background: var(--carbon-2); color: var(--ink); }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 22px; }
.form-grid .full { grid-column: 1 / -1; }
.form-status { margin-top: 12px; font-weight: 600; font-size: .95rem; display: none; }
.form-status.ok  { display: block; color: var(--ok); }
.form-status.err { display: block; color: var(--danger); }

/* ============================================================
   TRUST ROWS
   ============================================================ */
.trust-row, .trust {
  list-style: none;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px 26px;
  margin: 24px 0 0;
  padding: 0;
}
.trust-row li, .trust li {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: .85rem;
  font-weight: 500;
  color: var(--ink-soft);
}
.trust-row li::before, .trust li::before {
  content: "✓";
  display: inline-grid;
  place-items: center;
  width: 19px; height: 19px;
  border-radius: 50%;
  background: rgba(200, 50, 63, .16);
  color: var(--brand-bright);
  font-size: .66rem;
  font-weight: 800;
  flex-shrink: 0;
}
.trust-row.left, .trust.left { justify-content: flex-start; }
.trust { justify-content: flex-start; }
.page-hero .trust, .trust.center { justify-content: center; }

/* ============================================================
   GUARANTEE BAND
   ============================================================ */
.guarantee {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 20px;
  max-width: 840px;
  margin: 0 auto;
  padding: 26px 32px;
  border-radius: var(--radius);
  background: linear-gradient(120deg, rgba(200, 50, 63, .14), rgba(255, 255, 255, .03) 130%);
  border: 1px solid var(--brand-line);
  box-shadow: var(--shadow);
}
.guarantee svg { width: 46px; height: 46px; fill: var(--brand-bright); flex-shrink: 0; }
.guarantee p { margin: 0; font-size: .96rem; color: var(--ink-soft); }
.guarantee strong { color: #fff; }

/* ============================================================
   FOOTER
   ============================================================ */
.footer {
  position: relative;
  background: var(--void);
  background-image: var(--grain);
  background-blend-mode: overlay;
  padding: 64px 0 28px;
  color: #969ba5;
  overflow: hidden;
}
.footer::before {
  content: "";
  position: absolute;
  top: -150px; left: 50%;
  transform: translateX(-50%);
  width: 800px; height: 320px;
  background: radial-gradient(ellipse at center, rgba(200, 50, 63, .2), transparent 68%);
  pointer-events: none;
}
.footer .container, .footer .wrap { position: relative; }
.footer .foot-logo { display: flex; justify-content: center; margin-bottom: 32px; }
.footer .foot-logo img { height: 120px; filter: drop-shadow(0 12px 34px rgba(200, 50, 63, .4)); }
.footer-cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 38px; text-align: center; }
.footer h4 {
  font-family: var(--fd);
  font-weight: 500;
  text-transform: uppercase;
  color: #fff;
  font-size: 1.1rem;
  margin-bottom: 12px;
  letter-spacing: .16em;
}
.footer p { color: #969ba5; font-size: .94rem; }
.footer a { color: #d3d7de; transition: color .2s ease; }
.footer a:hover { color: var(--brand-bright); }
.footer .socials, .socials { display: flex; justify-content: center; gap: 15px; margin: 38px 0 28px; }
.socials a {
  width: 44px; height: 44px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .15);
  display: grid;
  place-items: center;
  transition: border-color .25s ease, background .25s ease, transform .25s var(--ease);
}
.socials a:hover {
  border-color: var(--brand);
  background: var(--brand);
  transform: translateY(-3px);
  box-shadow: 0 10px 26px rgba(158, 27, 43, .55);
}
.socials svg { width: 19px; height: 19px; fill: #fff; }
.copyright {
  border-top: 1px solid rgba(255, 255, 255, .08);
  padding-top: 26px;
  text-align: center;
  font-size: .84rem;
  color: #6c717b;
}
.copyright .built { display: block; margin-top: 8px; font-size: .8rem; }

/* ============================================================
   STICKY MOBILE ACTION BAR (injected by main.js)
   ============================================================ */
.sticky-cta {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 90;
  display: none;
  gap: 10px;
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  background: rgba(8, 8, 11, .94);
  border-top: 1px solid rgba(200, 50, 63, .28);
  box-shadow: 0 -10px 34px rgba(0, 0, 0, .6);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  transform: translateY(115%);
  transition: transform .38s var(--ease);
}
.sticky-cta.up { transform: translateY(0); }
.sticky-btn {
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 10px;
  border-radius: var(--radius-btn);
  font-family: var(--fb);
  font-weight: 800;
  font-size: .76rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  white-space: nowrap;
  border: 1.5px solid transparent;
  transition: transform .2s ease;
}
.sticky-btn svg { width: 17px; height: 17px; fill: currentColor; flex-shrink: 0; }
.sticky-btn.primary {
  flex: 1.35;
  background: linear-gradient(180deg, var(--brand-lift), var(--brand-deep));
  color: #fff;
  box-shadow: 0 8px 24px rgba(158, 27, 43, .6);
}
.sticky-btn.ghost {
  background: rgba(255, 255, 255, .07);
  color: #eef2f7;
  border-color: rgba(255, 255, 255, .18);
}
.sticky-btn:active { transform: scale(.97); }

@media (max-width: 880px) {
  .sticky-cta { display: flex; }
  body.has-sticky-cta .footer { padding-bottom: 96px; }
}

/* ============================================================
   MOTION — reveals, stagger, counters
   ============================================================ */
html.js .reveal {
  opacity: 0;
  /* a touch of scale alongside the rise — it reads as the panel settling into
     place rather than sliding, which is the difference between "animated" and
     "expensive". transform resolves to none once shown, so no stacking context
     is left behind on the section afterwards. */
  transform: translateY(26px) scale(.985);
  transition: opacity .9s var(--ease), transform .9s var(--ease);
  transition-delay: var(--d, 0ms);
}
html.js .reveal.visible { opacity: 1; transform: none; }

/* children of a .stagger container cascade in */
html.js .stagger > * {
  opacity: 0;
  transform: translateY(22px) scale(.985);
  transition: opacity .78s var(--ease), transform .78s var(--ease);
  transition-delay: var(--d, 0ms);
}
html.js .stagger.visible > * { opacity: 1; transform: none; }

/* count-up numerals hold their width so nothing jumps */
.count { font-variant-numeric: tabular-nums; }

/* ============================================================
   MOTION EXTRAS
   Pointer-driven or one-shot, and all of it is killed by the
   reduced-motion block at the end of this file.
   ============================================================ */

/* ---------- magnetic CTAs (main.js writes --tx/--ty) ---------- */
.btn.magnetic {
  transform: translate(var(--tx, 0px), var(--ty, 0px));
  transition: transform .18s var(--ease), box-shadow .25s var(--ease), background .2s ease;
}
.btn.magnetic:hover { transform: translate(var(--tx, 0px), calc(var(--ty, 0px) - 3px)); }

/* ---------- click ripple ---------- */
.btn .ripple {
  position: absolute;
  border-radius: 50%;
  background: rgba(255, 255, 255, .4);
  transform: scale(0);
  opacity: .8;
  pointer-events: none;
  animation: ripple-out .62s var(--ease) forwards;
  z-index: 0;
}
.btn-ghost .ripple, .btn-outline .ripple { background: rgba(200, 50, 63, .4); }
@keyframes ripple-out { to { transform: scale(2.6); opacity: 0; } }

/* ---------- water beading ----------
   Hydrophobic beads rolling off the paint — on a detailing site it reads
   as the product working. Injected by main.js, never blocks pointers. */
.bead-field {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 1;
}
.bead {
  position: absolute;
  top: -12%;
  border-radius: 50%;
  background:
    radial-gradient(circle at 32% 28%, rgba(255, 255, 255, .85), rgba(255, 255, 255, .1) 42%, rgba(255, 255, 255, 0) 62%),
    radial-gradient(circle at 65% 72%, rgba(224, 80, 92, .45), rgba(224, 80, 92, 0) 70%);
  box-shadow: inset 0 -1px 3px rgba(255, 255, 255, .45), 0 2px 6px rgba(0, 0, 0, .35);
  opacity: 0;
  animation: bead-roll linear infinite;
}
@keyframes bead-roll {
  0%   { transform: translateY(0) scale(.85); opacity: 0; }
  12%  { opacity: .8; }
  78%  { opacity: .62; }
  100% { transform: translateY(115vh) scale(1); opacity: 0; }
}

/* ---------- wet-paint sheen on card imagery ---------- */
.service-card .media,
.numbered-card .media,
.gallery-grid a,
.proof-strip a,
.proof-grid a { position: relative; }
.service-card .media::before,
.numbered-card .media::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  background: linear-gradient(104deg, transparent 42%, rgba(255, 255, 255, .26) 50%, transparent 58%);
  transform: translateX(-110%);
  transition: transform .85s var(--ease);
  pointer-events: none;
}
.service-card:hover .media::before,
.numbered-card:hover .media::before { transform: translateX(110%); }

/* ---------- booking total pulse (main.js toggles .bump) ---------- */
.wiz-total .amt.bump { animation: amt-bump .45s var(--ease); }
@keyframes amt-bump {
  0%   { transform: scale(1); }
  38%  { transform: scale(1.16); color: #fff; }
  100% { transform: scale(1); }
}

/* ---------- nav logo catches the light on hover ---------- */
.nav-brand:hover img { animation: logo-tilt .7s var(--ease); }
@keyframes logo-tilt {
  30% { transform: rotate(-4deg) scale(1.06); }
  60% { transform: rotate(2deg) scale(1.03); }
  100%{ transform: none; }
}

/* ---------- guarantee shield pulses once when it arrives ---------- */
.reveal.visible .guarantee svg { animation: shield-in .8s var(--ease) both; }
@keyframes shield-in {
  from { transform: scale(.6) rotate(-12deg); opacity: 0; }
  60%  { transform: scale(1.1) rotate(3deg); opacity: 1; }
  to   { transform: none; opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal, .stagger > * { opacity: 1 !important; transform: none !important; transition: none !important; }
  .bead-field { display: none; }
  .btn .ripple { display: none; }
  .btn.magnetic { transform: none !important; }
  * { transition-duration: .01ms !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; }
}

/* ============================================================
   RESPONSIVE — shared chrome
   ============================================================ */
@media (max-width: 1220px) {
  .nav-toggle { display: block; flex-shrink: 0; }

  /* The <nav> wrapper stays in the flex row once its links collapse into the
     burger menu, and `space-between` then distributes around that empty box —
     which is what left the phone button stranded mid-header. Pack everything
     after the logo to the right instead, so the phone sits beside the burger.
     The dropdown is positioned against .nav (sticky), not <nav>, so zeroing
     this out doesn't affect it. */
  .nav-inner { justify-content: flex-start; }
  .nav-inner > nav { flex: 0 0 0; width: 0; }
  .nav-brand { margin-right: auto; }

  .nav-links {
    position: absolute;
    top: 100%; left: 0; right: 0;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    background: rgba(8, 8, 11, .985);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border-bottom: 1px solid rgba(200, 50, 63, .28);
    box-shadow: 0 18px 44px rgba(0, 0, 0, .6);
    padding: 10px 5% 20px;
    display: none;
  }
  .nav-links.open { display: flex; animation: navdrop .3s var(--ease); }
  @keyframes navdrop { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: none; } }
  .nav-links li { width: 100%; border-bottom: 1px solid rgba(255, 255, 255, .07); }
  .nav-links li:last-child { border-bottom: none; }
  .nav-links a { display: block; padding: 15px 0; font-size: .95rem; letter-spacing: .12em; }
  .nav-links a::after { display: none; }
  .nav-links .mobile-only { display: block; }
}

@media (max-width: 880px) {
  .nav-inner { gap: 12px; }
  .nav-brand { gap: 9px; min-width: 0; }
  .nav-brand img { height: 54px; }
  .nav-brand .brand-name { font-size: .6rem; max-width: 96px; letter-spacing: .2em; }
  .nav-phone { width: 42px; height: 42px; }
  .nav-cta { display: none; }
}

/* Small phones: let the brand block shrink, then drop the tagline —
   the shield alone is enough. */
@media (max-width: 560px) {
  .nav-brand { flex-shrink: 1; min-width: 0; }
  .nav-brand .brand-name { display: none; }
}
@media (max-width: 400px) {
  .nav-inner { gap: 8px; padding: 9px 0; }
  .nav-brand img { height: 46px; }
  .nav-phone { width: 40px; height: 40px; border-radius: 11px; }
  .nav-phone svg { width: 20px; height: 20px; }
  .nav-toggle { padding: 9px; }
  .nav-toggle span { width: 20px; }
}

/* Inline call/text links are real conversions — give them a proper tap
   area on phones without changing how they read. */
@media (max-width: 880px) {
  p a[href^="tel:"],
  p a[href^="sms:"],
  .footer p a,
  .fc-note a {
    display: inline-block;
    padding-block: 11px;
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 1px;
  }
}

@media (max-width: 620px) {
  body { font-size: 16px; }
  .btn { padding: 14px 26px; }
  .footer-cols { grid-template-columns: 1fr; gap: 30px; }
  .footer .foot-logo img { height: 96px; }
  .guarantee { flex-direction: column; text-align: center; gap: 14px; padding: 26px 22px; }
  .trust-row, .trust { gap: 8px 18px; }
  .trust-row li, .trust li { font-size: .81rem; }
  .btn-row { margin-top: 30px; }
}

/* ---------- hero headline entrance ----------
   Defined here rather than in the page sheets so the contact lander gets it
   too — it loads lander.css, which never had these rules, so its headline and
   quote card simply appeared while everything around them faded in. */
.hero h1 .word { display: inline-block; white-space: nowrap; }
.hero h1 .ltr {
  display: inline-block;
  opacity: 0;
  transform: translateY(.4em);
  animation: letter-in .34s var(--ease) forwards;
}
@keyframes letter-in { to { opacity: 1; transform: none; } }

.hero-follow { opacity: 0; animation: follow-in .55s ease forwards; }
@keyframes follow-in {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .hero h1 .ltr, .hero-follow { opacity: 1 !important; transform: none !important; animation: none !important; }
}

/* ============================================================
   PAGE ENTRANCE
   A short staged arrival on every page: the strip, bar and nav
   settle first, then the hero. ~1.1s end to end at the longest,
   so it reads as the page composing itself rather than as a wait.

   Applied by JS, so nothing is ever hidden if the script fails —
   and skipped entirely under reduced-motion.
   ============================================================ */
html.js .page-in {
  opacity: 0;
  animation: page-in .62s var(--ease) both;
}
/* fade only — used on the sticky nav and the thin bars, where a transform
   would create a containing block and break stickiness while it runs */
html.js .page-in-soft {
  opacity: 0;
  animation: page-in-soft .55s ease both;
}
@keyframes page-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
@keyframes page-in-soft {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* safety net: if animations are throttled (background tab), force the end
   state so a page can never be left sitting blank */
html.js.intro-done .page-in,
html.js.intro-done .page-in-soft {
  opacity: 1 !important;
  transform: none !important;
  animation: none !important;
}

@media (prefers-reduced-motion: reduce) {
  html.js .page-in, html.js .page-in-soft {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
  }
}
