/* ===== DESIGN TOKENS — BLACK CHAUFFEUR + KEY WEST WARMTH =====
   Single source of truth for every visual value on the site.
   See docs/design-system/ for the full reference and rules. */
:root {
  /* Black/charcoal base — matches their chauffeur photo + white logo */
  --black:          #0A0A0B;
  --black-rich:     #050506;
  --charcoal:       #131316;
  --charcoal-light: #1C1C20;
  --charcoal-line:  #26262B;

  /* Brass / champagne — Key West sunset warmth (restrained) */
  --brass:          #C9A961;
  --brass-light:    #E5C988;
  --brass-deep:     #A88944;
  --brass-rgb:      201, 169, 97;
  --brass-glow:     rgba(var(--brass-rgb), 0.20);

  /* Brass overlays — four intents; snap new alphas to one of these */
  --brass-overlay-subtle: rgba(var(--brass-rgb), 0.12);  /* faint tints, hairline borders */
  --brass-overlay-medium: rgba(var(--brass-rgb), 0.25);  /* visible rules, panel borders  */
  --brass-overlay-strong: rgba(var(--brass-rgb), 0.4);   /* resting glows, focus rings    */
  --brass-overlay-peak:   rgba(var(--brass-rgb), 0.55);  /* elevated hover/active glows   */

  /* Subtle Key West coral accent — used sparingly */
  --conch:          #C75D49;
  --success:        #2A7A4A;   /* form success confirmation */

  /* Whites / ivories */
  --white:          #FFFFFF;
  --ivory:          #F2EBD9;
  --ivory-mute:     #B5AE9C;
  --ivory-dim:      #75705F;   /* decorative only — fails AA as body text on dark */

  /* Scrims — near-black overlays over photography */
  --scrim-soft:  rgba(5,5,6,0.55);
  --scrim:       rgba(5,5,6,0.78);
  --scrim-heavy: rgba(5,5,6,0.85);
  --scrim-solid: rgba(5,5,6,0.96);

  /* Type */
  --font-display: 'Playfair Display', Georgia, serif;
  --font-body:    'Lora', Georgia, serif;
  --font-label:   'Bebas Neue', Impact, sans-serif;

  /* Type scale — component sizes (pick the nearest step) */
  --text-2xs:  0.72rem;   /* fine print: breadcrumbs, badges, tiny labels */
  --text-xs:   0.78rem;   /* form labels, small caps labels               */
  --text-sm:   0.85rem;   /* eyebrows, inline CTAs                        */
  --text-base: 0.95rem;   /* the UI workhorse: card copy, chat, buttons   */
  --text-body: 1rem;      /* long-form body copy (the body default)       */
  --text-md:   1.05rem;   /* leads, testimonial text                      */
  --text-lg:   1.25rem;   /* small headings                               */
  --text-xl:   1.5rem;    /* panel titles, mobile nav                     */
  --text-2xl:  1.85rem;   /* large standalone numbers/phone               */

  /* Fluid display sizes (Playfair headings) */
  --display-hero:  clamp(2.75rem, 8vw, 5.75rem);
  --display-title: clamp(2.25rem, 5vw, 3.5rem);
  --display-sub:   clamp(1.8rem, 4vw, 2.6rem);
  --display-page:  clamp(2.4rem, 6vw, 4rem);      /* interior page-hero h1   */
  --display-stat:  clamp(2.75rem, 5vw, 3.75rem);  /* about stat numbers      */
  --display-faq:   clamp(1.05rem, 2.2vw, 1.3rem); /* FAQ questions           */
  --display-quote: 4.5rem;                        /* decorative quote glyph  */

  /* Letter-spacing (tracking) — the Bebas label look */
  --track-tight:   -0.01em;  /* Playfair display headings        */
  --track-wide:    0.05em;   /* slightly opened UI text          */
  --track-caps:    0.2em;    /* compact caps labels              */
  --track-label:   0.24em;   /* THE label tracking: nav, buttons, tags */
  --track-eyebrow: 0.4em;    /* section eyebrows                 */

  /* Spacing — quarter-rem (4px) scale */
  --space-1:  0.25rem;
  --space-2:  0.5rem;
  --space-3:  0.75rem;
  --space-4:  1rem;
  --space-5:  1.25rem;
  --space-6:  1.5rem;
  --space-7:  1.75rem;
  --space-8:  2rem;
  --space-9:  2.25rem;
  --space-10: 2.5rem;
  --space-11: 2.75rem;
  --space-12: 3rem;
  --space-16: 4rem;
  --space-18: 4.5rem;
  --space-20: 5rem;
  --space-24: 6rem;
  --space-section:    6.5rem;  /* standard section padding */
  --space-section-lg: 7rem;    /* hero / closing CTA       */
  --space-section-fluid: clamp(4rem, 9vw, 7rem);  /* fluid section padding: FAQ, articles, detail/contact layouts */

  --space-layout: clamp(2rem, 5vw, 4.5rem);      /* gap between the two columns of a content/media layout */

  /* Layout */
  --max-w: 1200px;
  --gutter: clamp(1.25rem, 4vw, 2.5rem);

  /* Measures — max widths for text blocks and narrow columns */
  --measure-prose:  820px;  /* reading column: articles, FAQ, hero copy      */
  --measure-header: 720px;  /* centred section header                        */
  --measure-lead:   620px;  /* lead paragraphs under a hero h1               */
  --measure-wide:   960px;  /* a centred two-up grid (testimonials)          */
  --measure-xs:     320px;  /* narrow column: footer tagline, stacked buttons */

  /* Line height */
  --leading-none:    1;     /* stat numerals, glyphs                    */
  --leading-display: 1.05;  /* hero and page-hero h1                    */
  --leading-tight:   1.1;   /* section titles and h2s                   */
  --leading-snug:    1.2;   /* compact UI titles (chat header)          */
  --leading-chat:    1.5;   /* chat bubbles and prechat copy            */
  --leading-body:    1.75;  /* the body default, card copy              */
  --leading-prose:   1.8;   /* long-form: articles, service copy, FAQ   */
  --leading-relaxed: 1.85;  /* airy leads: about, testimonials, CTA sub */

  /* Stacking — named layers instead of loose z-index numbers */
  --z-bg:       0;           /* photo layer inside a hero/CTA      */
  --z-overlay:  1;           /* scrim over that photo              */
  --z-content:  2;           /* copy above the scrim               */
  --z-drawer:   99;          /* mobile menu, just under the nav    */
  --z-nav:      100;         /* fixed site nav                     */
  --z-dropdown: 120;         /* desktop services dropdown          */
  --z-skip:     999;         /* skip link, above everything in-page */
  --z-chat:     2147483000;  /* chat launcher: above third-party UI */

  /* Sizes — fixed component dimensions */
  --tap-min:       44px;   /* minimum touch target                */
  --logo-h:        44px;   /* nav logo (sets the 77px nav height) */
  --logo-h-footer: 56px;
  --avatar:        52px;   /* testimonial portrait                */
  --rule-w:        32px;   /* eyebrow flanking rule               */
  --rule-w-sm:     20px;   /* eyebrow rule on a phone             */
  --rule-w-lg:     60px;   /* hero rope line                      */
  --chat-launcher: 60px;   /* round launcher button               */
  --chat-bar-h:    56px;   /* launcher as a phone bottom bar      */
  --chat-offset:   74px;   /* launcher + gap: window/toast sit above it */
  --chat-w:        370px;
  --chat-h:        540px;
  --chat-reserve:  120px;  /* viewport kept clear above the chat window */
  --chat-toast-w:  280px;
  --badge:         20px;   /* unread badge diameter               */

  /* Opacity */
  --opacity-faint:    0.25;  /* decorative glyphs                     */
  --opacity-veil:     0.28;  /* page-hero photo under its scrim       */
  --opacity-soft:     0.55;  /* hairline rules, de-emphasised states  */
  --opacity-disabled: 0.6;
  --opacity-strong:   0.8;   /* placeholders                          */

  /* Effects */
  --gradient-brass:       linear-gradient(145deg, var(--brass-light), var(--brass-deep)); /* brass controls */
  --gradient-brass-muted: linear-gradient(145deg, var(--brass-deep), var(--brass));       /* visitor chat bubble */
  --gradient-hairline:    linear-gradient(to right, transparent, var(--brass), transparent); /* the brass hairline motif */
  --photo-hero:   brightness(0.55) saturate(0.85);  /* home hero photo treatment   */
  --photo-cta:    brightness(0.4) saturate(0.9);    /* closing CTA photo treatment */
  --logo-filter:  brightness(0) invert(1);          /* logo artwork to flat white  */
  --blur-glass:   blur(16px);                       /* nav, dropdown               */
  --blur-panel:   blur(8px);                        /* booking form panel          */
  --hover-brighten: brightness(1.08);               /* gradient buttons on hover   */
  --focus-ring:   0 0 0 3px var(--brass-glow);      /* form field focus glow       */
  --focus-offset: 3px;                              /* keyboard outline offset     */
  --underline-offset: 4px;

  /* Motion offsets */
  --lift:         -4px;  /* card hover lift      */
  --lift-sm:      -2px;  /* button hover lift    */
  --press:        1px;   /* :active press        */
  --enter-shift:  8px;   /* dropdown/toast/chat window entrance, scroll-cue bounce */
  --reveal-shift: 20px;  /* scroll-reveal travel */
  --radius: 2px;
  --radius-lg: 4px;
  --radius-xl: 14px;
  --radius-pill: 999px;
  --radius-round: 50%;

  /* Motion */
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --dur-fast: 0.2s;   /* color/opacity hovers      */
  --dur-base: 0.3s;   /* borders, small transforms */
  --dur-slow: 0.4s;   /* card lifts, larger moves  */
  --dur-slower: 0.6s; /* scroll reveals, image zooms */

  /* Shadows (colors stay raw here — shadows are not scrims) */
  --shadow-card:       0 12px 40px rgba(0,0,0,0.55);
  --shadow-card-hover: 0 20px 56px rgba(0,0,0,0.7);
  --shadow-cta:        0 10px 32px rgba(var(--brass-rgb), 0.30);
  --shadow-glow:       0 8px 32px var(--brass-overlay-subtle);  /* resting brass glow   */
  --shadow-glow-hover: 0 12px 34px var(--brass-overlay-peak);   /* elevated hover glow  */
  --shadow-text:       0 4px 30px rgba(0,0,0,0.7);               /* hero headline over a photo */
}

/* ===== RESET ===== */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* scroll-padding-top keeps anchor and focus scrolling clear of the fixed nav
   (77px: 44px logo + two --space-4 + the hairline). Without it the skip link
   drops <main> underneath the header, and it is also what makes the form's
   focus-the-invalid-field behaviour land the field in view. */
html { scroll-behavior: smooth; scroll-padding-top: var(--space-24); }
body {
  background: var(--black);
  color: var(--ivory);
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
}
img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; }

/* ===== UTILS ===== */
.container {
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* ===== SECTION — one shell for every content band =====
   Every band below the hero is a .section; modifiers set its surface:
     .section--rich   the deeper black (alternating bands, FAQ, articles)
     .section--ruled  hairline rules top and bottom (about, testimonials)
     .section--fluid  fluid padding for text-led bands (FAQ, article, detail, contact)
   Heroes (.hero, .page-hero) and the closing CTA (.cta-closing) are their own
   components because they layer a photo, a scrim and copy. */
.section {
  padding: var(--space-section) 0;
  background: var(--black);
}
.section--rich  { background: var(--black-rich); }
.section--ruled {
  border-top: 1px solid var(--charcoal-line);
  border-bottom: 1px solid var(--charcoal-line);
}
.section--fluid { padding: var(--space-section-fluid) 0; }

.section-header {
  text-align: center;
  margin-bottom: var(--space-16);
  max-width: var(--measure-header);
  margin-left: auto;
  margin-right: auto;
}

/* ===== LABEL — the Bebas caps voice, defined once =====
   Every small-caps label on the site (eyebrows, tags, CTAs, nav, form labels,
   meta lines, breadcrumbs, buttons) speaks with this one voice. The groups below
   are the only place its font, case, tracking, size steps and tones are set;
   component rules keep only their layout. For a new standalone label in markup,
   use the utility: `.label` (xs, brass) plus at most one size and one tone:
     size   .label--eyebrow (sm, wide tracking)  .label--action (sm)  .label--fine (2xs)
     tone   .label--muted (ivory-mute)           .label--dim (ivory-dim, fine print only)
   Tracking rule: --track-label everywhere; --track-eyebrow only on eyebrows. */
.label, label, .btn,
.section-eyebrow, .hero-eyebrow, .hero-meta, .scroll-label,
.card-tag, .card-cta, .inline-cta, .card-meta, .article-meta,
.stat-label, .author-detail, .phone-label, .breadcrumb, .contact-detail .label,
.footer-col .footer-heading, .footer-meta,
.nav-menu > li > a, .dropdown-toggle, .skip-link,
.kwgt-toast-label, .kwgt-toggle-label {
  font-family: var(--font-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
}
/* Eyebrow tracking */
.label--eyebrow, .section-eyebrow, .hero-eyebrow, .hero-meta, .scroll-label {
  letter-spacing: var(--track-eyebrow);
}
/* Size steps */
.label--eyebrow, .label--action,
.section-eyebrow, .hero-eyebrow, .hero-meta,
.card-cta, .inline-cta, .nav-menu > li > a, .dropdown-toggle, .skip-link {
  font-size: var(--text-sm);
}
.label, label, .stat-label, .phone-label, .footer-col .footer-heading {
  font-size: var(--text-xs);
}
.label--fine, .scroll-label, .card-tag, .card-meta, .article-meta,
.author-detail, .breadcrumb, .contact-detail .label, .kwgt-toast-label {
  font-size: var(--text-2xs);
}
/* Tones */
.label, label,
.section-eyebrow, .hero-eyebrow, .hero-meta,
.card-tag, .card-cta, .inline-cta,
.author-detail, .phone-label, .contact-detail .label,
.footer-col .footer-heading, .kwgt-toast-label {
  color: var(--brass);
}
.label--muted, .scroll-label, .stat-label, .nav-menu > li > a, .dropdown-toggle {
  color: var(--ivory-mute);
}
.label--dim, .card-meta, .article-meta, .breadcrumb {
  color: var(--ivory-dim);
}

/* ===== DISPLAY — the Playfair heading voice, defined once =====
   Every heading-style line (hero and page h1s, section/CTA titles, service and
   article h2s, card and form titles, the phone number, stats, names) shares this
   voice; component rules keep only size, line height and spacing. One weight:
   700 is the only Playfair weight the site loads in both upright and italic. */
.hero-headline, .page-hero h1, .section-title, .cta-title,
.service-detail-copy h2, .article-prose h2,
.card-title, .form-title, .phone-number, .stat-number, .author-name, .kwgt-chat-title {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: var(--track-tight);
  color: var(--white);
}
/* The accent: the italic, brass-light second line of a two-line heading
   ("Key West Group / *Transportation*"). One rule for every heading that has one. */
.hero-headline em, .page-hero h1 em, .section-title em, .cta-title em, .service-detail-copy h2 em {
  font-style: italic;
  font-weight: 700;
  color: var(--brass-light);
}
/* Section and CTA titles are one size and leading; the CTA adds its gap below. */
.section-title, .cta-title {
  font-size: var(--display-title);
  line-height: var(--leading-tight);
}

.section-eyebrow {
  margin-bottom: var(--space-4);
  display: inline-flex;
  align-items: center;
  gap: 0.85em;
}
.section-eyebrow::before,
.section-eyebrow::after {
  content: '';
  display: inline-block;
  width: var(--rule-w);
  height: 1px;
  background: var(--brass);
  opacity: var(--opacity-soft);
}


.section-sub {
  font-size: var(--text-md);
  color: var(--ivory-mute);
  margin-top: var(--space-5);
  font-style: italic;
  line-height: var(--leading-prose);
}

/* Centered standalone CTA below a grid (e.g. home fleet "View the Full Fleet") */
.section-cta {
  text-align: center;
  margin-top: var(--space-10);
}

.btn {
  display: inline-block;
  font-size: var(--text-base);
  padding: 1.1em 2.5em;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background var(--dur-base), color var(--dur-base), border-color var(--dur-base), box-shadow var(--dur-base), transform var(--dur-base);
  border: 1px solid transparent;
}

.btn-gold {
  background: var(--brass);
  color: var(--black-rich);
  border-color: var(--brass);
  font-weight: 400;
}
.btn-gold:hover {
  background: var(--brass-light);
  border-color: var(--brass-light);
  box-shadow: var(--shadow-cta);
  transform: translateY(var(--lift-sm));
}

.btn-outline {
  background: transparent;
  color: var(--white);
  border-color: var(--white);
}
.btn-outline:hover {
  background: var(--white);
  color: var(--black-rich);
}

.btn--full { width: 100%; text-align: center; }

/* One disabled state for every button (quote form while sending, chat start). */
.btn:disabled,
.btn:disabled:hover {
  opacity: var(--opacity-disabled);
  cursor: default;
  transform: none;
  box-shadow: none;
}

/* Success confirmation state (set by JS after the quote form submits) */
.btn--success,
.btn--success:hover {
  background: var(--success);
  border-color: var(--success);
  color: var(--white);
  box-shadow: none;
  transform: none;
}

/* ===== NAV ===== */
.site-nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: var(--z-nav);
  background: var(--scrim);
  backdrop-filter: var(--blur-glass);
  border-bottom: 1px solid var(--brass-overlay-subtle);
}

.nav-inner {
  max-width: var(--max-w);
  margin: 0 auto;
  padding: var(--space-4) var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.nav-logo { display: flex; align-items: center; }
.logo-img {
  height: var(--logo-h);
  width: auto;
  filter: var(--logo-filter);
}

.nav-links {
  display: flex;
  align-items: center;
  gap: var(--space-8);
}

/* ===== HERO ===== */
.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;  /* stable small viewport: vh is the toolbar-expanded height on iOS */
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-section-lg) var(--gutter) var(--space-20);
  overflow: hidden;
}

.hero-bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  z-index: var(--z-bg);
  filter: var(--photo-hero);
}

.hero-overlay {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 80% 60% at 50% 50%, transparent 0%, var(--scrim-soft) 70%, var(--scrim-heavy) 100%),
    linear-gradient(180deg, var(--scrim-soft) 0%, transparent 30%, transparent 70%, var(--scrim-heavy) 100%);
}

.hero-content {
  position: relative;
  z-index: var(--z-content);
  max-width: var(--measure-prose);
}

.hero-eyebrow {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-5);
  margin-bottom: var(--space-7);
}

.rope-line {
  display: inline-block;
  width: var(--rule-w-lg);
  height: 1px;
  background: var(--gradient-hairline);
}

.hero-headline {
  font-size: var(--display-hero);
  line-height: var(--leading-display);
  margin-bottom: var(--space-7);
  text-shadow: var(--shadow-text);
}
.hero-headline em {
  display: block;
  font-size: 0.92em;
  margin-top: 0.1em;
}

.hero-sub {
  font-size: var(--text-md);
  color: var(--ivory);
  max-width: var(--measure-lead);
  margin: 0 auto var(--space-4);
  line-height: var(--leading-body);
}

.hero-meta {
  margin-bottom: var(--space-11);
}

.actions {
  display: flex;
  gap: var(--space-4);
  justify-content: center;
  flex-wrap: wrap;
}

.hero-scroll-cue {
  position: absolute;
  bottom: var(--space-8);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  z-index: var(--z-content);
}
.scroll-arrow {
  color: var(--brass);
  font-size: var(--text-md);
  animation: bounce 2s ease-in-out infinite;
}
@keyframes bounce {
  0%, 100% { transform: translateY(0); }
  50%       { transform: translateY(var(--enter-shift)); }
}

/* ===== CARDS — one component for every grid =====
   Vehicles, services, guides, values and testimonials all render as .card
   (build-pages.mjs card() for the first four). The surface is defined once here;
   variants add behaviour:
     .card--link      the whole card is a link: lift, brass border, image zoom, press
     .card--media     has a .card-media photo (phones turn it into a media object)
     .card--featured  brass border + resting glow; pairs with .card-tag--featured
     .card--center    centred text (value cards)
   Only .card--link moves on hover: a static card that lifts reads as clickable. */
.card-grid {
  display: grid;
  /* min() so the track can collapse below its ideal width instead of forcing
     horizontal page overflow on a sub-360px viewport. */
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  gap: var(--space-8);
}
.card-grid--compact { grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr)); }
.card-grid--narrow  { max-width: var(--measure-wide); margin: 0 auto; }

.card {
  /* Link cards are an <a>, inline by default. Equal specificity and declared
     before the phone rules, so the media-object grid below still wins. */
  display: block;
  position: relative;
  background: var(--charcoal);
  border: 1px solid var(--charcoal-line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.card--link {
  transition: transform var(--dur-slow), box-shadow var(--dur-slow), border-color var(--dur-slow);
}
.card--link:hover {
  transform: translateY(var(--lift));
  box-shadow: var(--shadow-card);
  border-color: var(--brass);
}
.card--featured {
  border-color: var(--brass);
  box-shadow: var(--shadow-glow);
}
.card--center { text-align: center; }

.card-media {
  position: relative;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  background: var(--charcoal-light);
}
.card-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slower) var(--ease-standard);
}
.card--link:hover .card-media img {
  transform: scale(1.06);
}
.card-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, transparent 60%, var(--scrim-soft) 100%);
  pointer-events: none;
}

.card-body { padding: var(--space-7); }
.card-media + .card-body { border-top: 1px solid var(--charcoal-line); }

.card-icon {
  font-size: var(--text-2xl);
  color: var(--brass);
  margin-bottom: var(--space-4);
}

.card-tag {
  display: inline-block;
  border: 1px solid var(--brass-overlay-strong);
  padding: 0.35em 1em;
  border-radius: var(--radius);
  margin-bottom: var(--space-4);
}
.card-tag--featured {
  background: var(--brass);
  color: var(--black-rich);
  border-color: var(--brass);
}

.card-title {
  font-size: var(--text-xl);
  line-height: var(--leading-snug);
  margin-bottom: var(--space-3);
}

.card-text {
  font-size: var(--text-base);
  color: var(--ivory-mute);
  line-height: var(--leading-body);
}
.card-text:not(:last-child) { margin-bottom: var(--space-6); }

.card-cta,
.inline-cta {
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur-base), color var(--dur-base);
}
.card-cta:hover,
.card--link:hover .card-cta,
.inline-cta:hover {
  color: var(--brass-light);
  border-color: var(--brass-light);
}

/* ===== ABOUT ===== */
.about-inner {
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  gap: var(--space-18);
  align-items: center;
}

.about-copy .section-title { text-align: left; margin-bottom: var(--space-7); }
.about-copy .section-eyebrow::before { display: none; }

.about-text {
  color: var(--ivory-mute);
  font-size: var(--text-body);
  line-height: var(--leading-relaxed);
  margin-bottom: var(--space-5);
}
.about-text:last-child { margin-bottom: 0; }

.about-stats {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  padding-left: var(--space-12);
  border-left: 1px solid var(--brass-overlay-medium);
}

.stat-item {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.stat-number {
  font-size: var(--display-stat);
  color: var(--brass-light);
  line-height: var(--leading-none);
}
.stat-plus {
  color: var(--conch);
  font-style: italic;
}

/* ===== TESTIMONIALS ===== */
.testimonial-stars {
  color: var(--brass);
  font-size: var(--text-base);
  letter-spacing: var(--track-caps);
  margin-bottom: var(--space-5);
}

.testimonial-text {
  font-style: italic;
  color: var(--ivory);
  font-size: var(--text-md);
  line-height: var(--leading-relaxed);
  margin-bottom: var(--space-7);
  position: relative;
}
.testimonial-text::before {
  content: '"';
  font-family: var(--font-display);
  font-size: var(--display-quote);
  color: var(--brass);
  opacity: var(--opacity-faint);
  position: absolute;
  top: calc(var(--space-9) * -1);
  left: calc(var(--space-3) * -1);
  line-height: var(--leading-none);
}

.testimonial-author {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding-top: var(--space-5);
  border-top: 1px solid var(--charcoal-line);
}

.author-portrait {
  width: var(--avatar);
  height: var(--avatar);
  border-radius: var(--radius-round);
  object-fit: cover;
  border: 2px solid var(--brass);
}

.author-name {
  display: block;
  font-size: var(--text-md);
}

.author-detail {
  display: block;
  margin-top: var(--space-1);
}

/* ===== CLOSING CTA / BOOKING ===== */
.cta-closing {
  position: relative;
  padding: var(--space-section-lg) 0;
  overflow: hidden;
}

.cta-bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  filter: var(--photo-cta);
  z-index: var(--z-bg);
}

.cta-overlay {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(135deg, var(--scrim-heavy) 0%, var(--scrim-soft) 50%, var(--scrim-heavy) 100%);
  z-index: var(--z-overlay);
}

.cta-content {
  position: relative;
  z-index: var(--z-content);
  display: grid;
  grid-template-columns: 1fr 1.15fr;
  gap: var(--space-18);
  align-items: center;
}

.cta-copy .section-eyebrow::before { display: none; }

.cta-title { margin-bottom: var(--space-6); }

.cta-sub {
  color: var(--ivory);
  font-size: var(--text-md);
  margin-bottom: var(--space-9);
  line-height: var(--leading-relaxed);
}

.cta-contact {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* Centered variant — interior-page closing CTA (buttons, no booking form) */
.cta-closing--center .cta-content { display: block; text-align: center; }
.cta-closing--center .cta-sub { margin-left: auto; margin-right: auto; }
.cta-closing--center .actions { justify-content: center; }

.cta-phone {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-5) var(--space-6);
  border: 1px solid var(--brass);
  border-radius: var(--radius-lg);
  background: var(--scrim-soft);
  transition: background var(--dur-base), border-color var(--dur-base);
}
.cta-phone:hover {
  background: var(--brass-overlay-subtle);
  border-color: var(--brass-light);
}

.phone-number { font-size: var(--text-2xl); }

.cta-email {
  font-size: var(--text-base);
  color: var(--ivory-mute);
  text-decoration: underline;
  text-decoration-color: var(--brass-overlay-medium);
  text-underline-offset: var(--underline-offset);
  transition: color var(--dur-base);
}
.cta-email:hover { color: var(--brass); }

/* Form */
.booking-form {
  background: var(--scrim-heavy);
  border: 1px solid var(--brass-overlay-medium);
  border-radius: var(--radius-lg);
  padding: var(--space-11);
  backdrop-filter: var(--blur-panel);
}

.form-title {
  font-size: var(--text-xl);
  margin-bottom: var(--space-7);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--charcoal-line);
}

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.form-group--full { grid-column: 1 / -1; margin-bottom: var(--space-4); }

label {
}
/* Required-field asterisk. Visual only: the input's `required` attribute is what
   screen readers announce, so the mark is aria-hidden. */
.required-mark {
  color: var(--conch);
  margin-left: var(--space-1);
}

input, select, textarea {
  background: var(--charcoal-light);
  border: 1px solid var(--charcoal-line);
  border-radius: var(--radius);
  color: var(--white);
  font-family: var(--font-body);
  font-size: var(--text-base);
  padding: 0.85em 1em;
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
  width: 100%;
}
input::placeholder, textarea::placeholder { color: var(--ivory-dim); opacity: var(--opacity-strong); }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--brass);
  box-shadow: var(--focus-ring);
}

select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M6 8L0 0h12z' fill='%23C9A961'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1em center;
  padding-right: 2.4em;
  cursor: pointer;
}

textarea { resize: vertical; min-height: 90px; }

/* Touch devices zoom the whole page when a focused field is under 16px and leave it
   zoomed. --text-body is exactly 1rem, so this is the smallest step that clears the
   threshold. Gated on the pointer rather than a width: a large phone in landscape is
   932 CSS px, i.e. above every max-width tier, and a mouse never matches. */
@media (hover: none) and (pointer: coarse) {
  input, select, textarea { font-size: var(--text-body); }
  /* 16px text needs the arrow reserve trimmed, or the longest service option
     ("Bachelorette / Bachelor Party") no longer fits the field. */
  select {
    padding-right: 2em;
    background-position: right 0.75em center;
    text-overflow: ellipsis;
  }
}

/* ===== FOOTER ===== */
.site-footer {
  background: var(--black-rich);
  color: var(--ivory);
  position: relative;
}

.footer-divider {
  height: 1px;
  background: var(--gradient-hairline);
  opacity: var(--opacity-soft);
}

.footer-top {
  display: grid;
  grid-template-columns: 1.8fr 1fr 1fr 1.2fr;
  gap: var(--space-12);
  padding: var(--space-18) 0 var(--space-12);
}

.footer-logo {
  height: var(--logo-h-footer);
  width: auto;
  filter: var(--logo-filter);
  margin-bottom: var(--space-5);
}

.footer-tagline {
  font-size: var(--text-base);
  color: var(--ivory-mute);
  max-width: var(--measure-xs);
  line-height: var(--leading-body);
  font-style: italic;
}

.footer-col .footer-heading {
  margin-bottom: var(--space-6);
}

/* --col-gap is the one link spacing for every footer column, including the
   services list inside its <details>, which sits outside the column's own gap. */
.footer-col { --col-gap: var(--space-3); display: flex; flex-direction: column; gap: var(--col-gap); }

/* The services list is a <details open> so it can collapse on a phone. On desktop
   it must read exactly as the plain column it replaced: no marker, no pointer
   affordance, and the same gap between the heading and the links. */
.footer-details > summary { list-style: none; cursor: default; }
.footer-details > summary::-webkit-details-marker { display: none; }
.footer-details > summary::marker { content: ''; }
/* Padding, not margin: a margin here collapses into the heading's bottom margin. */
.footer-links { display: flex; flex-direction: column; gap: var(--col-gap); padding-top: var(--col-gap); }
@media (min-width: 881px) {
  /* Not toggleable above the breakpoint, so the desktop footer cannot be collapsed. */
  .footer-details > summary { pointer-events: none; }
}
.footer-col a, .footer-col p {
  font-size: var(--text-base);
  color: var(--ivory-mute);
  transition: color var(--dur-fast);
}
.footer-col a:hover { color: var(--brass); }

.footer-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-7) 0;
  border-top: 1px solid var(--charcoal-line);
}

.footer-copy, .footer-meta {
  font-size: var(--text-xs);
  color: var(--ivory-dim);
}
.footer-meta {
  color: var(--brass);
}

/* ===== RESPONSIVE ===== */
@media (max-width: 960px) {
  /* 641-960 lays the stats out as a wrapping row (2x2 with four); the phone tier turns it back into a column. */
  .about-stats {
    padding-left: 0;
    border-left: none;
    border-top: 1px solid var(--brass-overlay-medium);
    padding-top: var(--space-8);
    flex-direction: row;
    justify-content: space-around;
    flex-wrap: wrap;
  }
  .footer-top {
    grid-template-columns: 1fr 1fr;
  }
  .footer-brand { grid-column: 1 / -1; }
}

@media (max-width: 640px) {
  .form-row { grid-template-columns: 1fr; }
  .footer-top { grid-template-columns: 1fr; }
  .footer-bottom { flex-direction: column; gap: var(--space-2); text-align: center; }
  .actions { flex-direction: column; align-items: center; width: 100%; }
  .actions .btn { width: 100%; max-width: var(--measure-xs); }
  .section-eyebrow::before,
  .section-eyebrow::after { width: var(--rule-w-sm); }


  /* The footer link column is the densest tap cluster on the site: 27px boxes
     12px apart. Widen the gap rather than the boxes -- padding on 13 links would
     add ~220px of footer to every page for the same result. */
  .footer-col { --col-gap: var(--space-4); }

  /* The stat rail flips to a wrapping row at 960 and stayed one down to 320px, which
     put 44px numerals and 0.24em-tracked labels in ~90px columns. Back to a
     column, but with each item on its own line so three items cost ~150px instead
     of the ~330px a full vertical stack would. */
  .about-stats {
    flex-direction: column;
    justify-content: flex-start;
    flex-wrap: nowrap;
    gap: var(--space-5);
  }
  .stat-item {
    flex-direction: row;
    align-items: baseline;
    gap: var(--space-3);
  }

  /* Headings carry a hard-coded <br/> chosen for desktop measure, which on a phone
     breaks early and spends a line on whitespace. The breaks are data, so they are
     neutralized here rather than removed. All 72 heading breaks are <br/><em> with
     no surrounding whitespace, so hiding one would run the words together --
     the generated space puts it back. The 404's two-line "404 / Off the Map." is
     deliberate, and the 22 address breaks are semantic, so both are left alone. */
  .hero-headline br,
  .section-title br,
  .cta-title br,
  .service-detail-copy h2 br,
  .page-hero:not(.page-hero--fill) h1 br { display: none; }

  .section-title br + em::before,
  .cta-title br + em::before,
  .service-detail-copy h2 br + em::before,
  .page-hero:not(.page-hero--fill) h1 br + em::before { content: ' '; }
}

/* ============================================
   FAQ
   ============================================ */
.faq-list {
  max-width: var(--measure-prose);
  margin: 0 auto;
}
.faq-item {
  border-bottom: 1px solid var(--charcoal-line);
  padding: var(--space-1) 0;
}
.faq-q {
  font-family: var(--font-display);
  font-size: var(--display-faq);
  font-weight: 700;
  color: var(--ivory);
  cursor: pointer;
  list-style: none;
  padding: var(--space-5) var(--space-10) var(--space-5) 0;
  position: relative;
  transition: color var(--dur-fast) var(--ease-standard);
}
.faq-q::-webkit-details-marker { display: none; }
.faq-q::after {
  content: '+';
  position: absolute;
  right: var(--space-1);
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--font-label);
  font-size: var(--text-xl);
  color: var(--brass);
}
.faq-item[open] .faq-q::after { content: '−'; }
.faq-q:hover { color: var(--brass-light); }
.faq-a {
  font-family: var(--font-body);
  color: var(--ivory-mute);
  line-height: var(--leading-prose);
  padding: 0 var(--space-10) var(--space-5) 0;
  margin: 0;
}
.faq-a a { color: var(--brass-light); }

/* ============================================
   GUIDES / ARTICLES
   ============================================ */
.article-meta,
.card-meta {
}
.article-meta {
  max-width: var(--measure-prose);
  margin: 0 auto var(--space-6);
}
.card-meta { margin-bottom: var(--space-6); }
.article-prose {
  max-width: var(--measure-prose);
  margin: 0 auto;
  font-family: var(--font-body);
  color: var(--ivory-mute);
  line-height: var(--leading-prose);
}
.article-prose h2 {
  font-size: var(--display-sub);
  line-height: var(--leading-tight);
  margin: var(--space-10) 0 var(--space-4);
}
.article-prose h2:first-child { margin-top: 0; }
.article-prose p { margin: 0 0 var(--space-4); }
.article-prose a { color: var(--brass-light); }
.article-prose strong { color: var(--ivory); font-weight: 600; }
.article-prose ul {
  margin: 0 0 var(--space-4);
  padding-left: var(--space-5);
}
.article-prose li { margin-bottom: var(--space-2); }
.article-prose li::marker { color: var(--brass); }

/* ============================================================
   MULTI-PAGE NAV (desktop menu + dropdown + mobile drawer)
   ============================================================ */
.site-nav.scrolled { background: var(--scrim-solid); }

.nav-menu {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  list-style: none;
}
.nav-menu > li { position: relative; }
.nav-menu > li > a,
.dropdown-toggle {
  transition: color var(--dur-fast);
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
}
.nav-menu > li > a:hover,
.dropdown-toggle:hover,
.nav-menu a.active,
.dropdown-toggle.active { color: var(--brass); }

/* Desktop dropdown */
.nav-menu .dropdown {
  position: absolute;
  top: calc(100% + var(--space-4));
  left: 50%;
  transform: translateX(-50%) translateY(var(--enter-shift));
  min-width: 248px;
  background: var(--scrim-solid);
  backdrop-filter: var(--blur-glass);
  border: 1px solid var(--charcoal-line);
  border-top: 2px solid var(--brass);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  list-style: none;
  padding: var(--space-2) 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-fast) var(--ease-standard), transform var(--dur-fast) var(--ease-standard), visibility var(--dur-fast);
  z-index: var(--z-dropdown);
}
.nav-menu li.open .dropdown {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}
.nav-menu .dropdown li { display: block; }

/* Shared sub-nav link recipe — the desktop dropdown and the mobile drawer's
   .mobile-sub links render the same service-link list, so they share one
   body-font style. Layout specifics stay with each context below. */
.nav-menu .dropdown a,
.mobile-menu .mobile-sub {
  font-family: var(--font-body);
  font-size: var(--text-base);
  color: var(--ivory-mute);
  transition: background var(--dur-fast), color var(--dur-fast);
}
.nav-menu .dropdown a:hover,
.mobile-menu .mobile-sub:hover { color: var(--brass-light); }

.nav-menu .dropdown a {
  display: block;
  padding: var(--space-3) var(--space-6);
  text-transform: none;
}
.nav-menu .dropdown a:hover { background: var(--charcoal-light); }

/* Hamburger */
/* 44×44 tap target (a11y baseline); the visible bars stay 30px wide
   inside the padding. */
.hamburger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: var(--tap-min);
  height: var(--tap-min);
  background: none;
  border: none;
  cursor: pointer;
  padding: 7px;
}
.hamburger span {
  display: block;
  height: 2px;
  width: 100%;
  background: var(--ivory);
  transition: transform var(--dur-base), opacity var(--dur-base);
}
.hamburger.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.hamburger.open span:nth-child(2) { opacity: 0; }
.hamburger.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Mobile drawer */
.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: var(--z-drawer);
  background: var(--black-rich);
  padding: var(--space-24) var(--gutter) var(--space-8);
  transform: translateX(100%);
  /* visibility flips after the slide-out so the closed drawer's links leave
     the tab order and the accessibility tree, without cutting the animation */
  visibility: hidden;
  transition: transform var(--dur-slow) var(--ease-standard),
              visibility 0s var(--dur-slow);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.mobile-menu.open {
  transform: translateX(0);
  visibility: visible;
  transition-delay: 0s;
}
/* Plain drawer links; the CTA at the bottom is a .btn and keeps its own recipe. */
.mobile-menu a:not(.btn) {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  color: var(--ivory);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--charcoal-line);
}
.mobile-menu a:not(.btn):hover, .mobile-menu a.active { color: var(--brass); }
/* Typography comes from the shared sub-nav recipe (see MULTI-PAGE NAV);
   the indent alone marks sub-links, matching the desktop dropdown's plain
   (bullet-free) list. */
.mobile-menu .mobile-sub { padding-left: var(--space-5); }
/* Mobile Services accordion: toggle row styled like a .mobile-menu link */
.mobile-services-toggle {
  background: none;
  border: 0;
  border-bottom: 1px solid var(--charcoal-line);
  text-align: left;
  cursor: pointer;
  min-height: var(--tap-min);
  font-family: var(--font-display);
  font-size: var(--text-xl);
  color: var(--ivory);
  padding: var(--space-3) 0;
}
.mobile-services-toggle:hover, .mobile-services-toggle.open, .mobile-services-toggle.active { color: var(--brass); }
.mobile-services-drawer { display: none; }
.mobile-services-drawer.open {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.mobile-menu .mobile-cta { margin-top: var(--space-6); }


/* ============================================================
   INTERIOR PAGE HERO + BREADCRUMB
   ============================================================ */
.page-hero {
  position: relative;
  padding: clamp(8rem, 16vw, 11rem) 0 clamp(3rem, 7vw, 5rem);
  text-align: center;
  overflow: hidden;
  border-bottom: 1px solid var(--charcoal-line);
}
.page-hero-bg {
  position: absolute; inset: 0;
  background-size: cover; background-position: center;
  opacity: var(--opacity-veil);
}
.page-hero::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, var(--scrim) 0%, var(--scrim-solid) 100%);
}
.page-hero .container { position: relative; z-index: var(--z-content); }
.page-hero h1 {
  font-size: var(--display-page);
  line-height: var(--leading-display);
}
.page-hero .page-sub {
  font-family: var(--font-body);
  color: var(--ivory-mute);
  max-width: var(--measure-lead);
  margin: var(--space-5) auto 0;
  font-size: var(--text-md);
  line-height: var(--leading-body);
}
.breadcrumb {
  margin-bottom: var(--space-6);
}
.breadcrumb a { color: var(--ivory-mute); transition: color var(--dur-fast); }
.breadcrumb a:hover { color: var(--brass); }
.breadcrumb span { color: var(--brass); }

/* Fill variant — the 404 page's viewport-height hero with centered actions */
.page-hero--fill {
  min-height: 70vh;
  min-height: 70svh;
  display: flex;
  align-items: center;
}
.page-hero--fill .actions {
  justify-content: center;
  margin-top: var(--space-8);
}

/* ============================================================
   SERVICE DETAIL
   ============================================================ */
.service-detail-inner {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: var(--space-layout);
  align-items: center;
}
/* A fixed 4:3 frame (the card photo ratio) so every service page shows the same
   shape whatever the source image: the corporate photo is portrait. */
.service-detail-img {
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-card);
}
.service-detail-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.service-detail-copy h2 {
  font-size: var(--display-sub);
  line-height: var(--leading-tight);
  margin-bottom: var(--space-5);
}
/* Body paragraphs only: the eyebrow is a <p> too, and a plain `p` here (0,1,1)
   beat .section-eyebrow (0,1,0), so it rendered as grey Lora on every service page. */
.service-detail-copy p:not(.section-eyebrow) {
  font-family: var(--font-body);
  color: var(--ivory-mute);
  line-height: var(--leading-prose);
  margin-bottom: var(--space-4);
}
.feature-list { list-style: none; margin: var(--space-6) 0 var(--space-8); }
.feature-list li {
  font-family: var(--font-body);
  color: var(--ivory);
  padding: var(--space-2) 0 var(--space-2) var(--space-8);
  position: relative;
}
.feature-list li::before {
  content: '✦';
  position: absolute; left: 0;
  color: var(--brass);
}

/* ============================================================
   CONTACT PAGE
   ============================================================ */
.contact-layout {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: var(--space-layout);
  align-items: start;
}
.contact-detail { margin-bottom: var(--space-7); }
.contact-detail .label {
  display: block;
  margin-bottom: var(--space-1);
}
.contact-detail a, .contact-detail p {
  font-family: var(--font-body);
  color: var(--ivory);
  font-size: var(--text-md);
}
.contact-detail a:hover { color: var(--brass); }
.form-error {
  color: var(--conch);
  font-family: var(--font-body);
  font-size: var(--text-base);
  margin-top: var(--space-3);
  min-height: 1.2em;
}
/* ============================================================
   LIVE CHAT WIDGET (Telegram-backed) — luxury dark + brass
   ============================================================ */
.kwgt-chat { position: fixed; bottom: var(--space-6); right: var(--space-6); z-index: var(--z-chat); font-family: var(--font-body); }
/* The launcher outranks the drawer (z-index 99), so while the drawer is open it
   paints over the last nav link and the drawer's own CTA. `nav-open` is set by the
   drawer handler in js/main.js. */
body.nav-open .kwgt-chat { display: none; }
.kwgt-toggle-label { display: none; }
.kwgt-toggle {
  width: var(--chat-launcher); height: var(--chat-launcher); border-radius: var(--radius-round);
  background: var(--gradient-brass);
  color: var(--black-rich);
  border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-cta);
  transition: transform var(--dur-base), box-shadow var(--dur-base);
  position: relative;
}
.kwgt-toggle:hover { transform: translateY(var(--lift-sm)) scale(1.04); box-shadow: var(--shadow-glow-hover); }
.kwgt-badge {
  position: absolute; top: calc(var(--space-1) * -1); right: calc(var(--space-1) * -1);
  min-width: var(--badge); height: var(--badge); padding: 0 var(--space-1);
  background: var(--conch); color: var(--white);
  border-radius: var(--radius-pill); font-size: var(--text-2xs); font-weight: 700;
  display: none; align-items: center; justify-content: center;
  font-family: var(--font-label); letter-spacing: var(--track-wide);
}
.kwgt-badge.visible { display: flex; }

.kwgt-chat-window {
  position: absolute; bottom: var(--chat-offset); right: 0;
  width: var(--chat-w); max-width: calc(100vw - var(--space-8)); height: var(--chat-h);
  max-height: calc(100vh - var(--chat-reserve)); max-height: calc(100svh - var(--chat-reserve));
  background: var(--charcoal);
  border: 1px solid var(--charcoal-line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card-hover);
  display: none; flex-direction: column; overflow: hidden;
}
.kwgt-chat-window.open { display: flex; animation: kwgtUp var(--dur-base) var(--ease-standard); }
@keyframes kwgtUp { from { opacity: 0; transform: translateY(var(--enter-shift)); } to { opacity: 1; transform: translateY(0); } }

.kwgt-chat-header {
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-4) var(--space-4);
  background: linear-gradient(135deg, var(--charcoal), var(--black));
  border-bottom: 1px solid var(--brass-deep);
}
.kwgt-chat-close {
  background: none; border: none; color: var(--ivory-mute); cursor: pointer;
  display: flex; padding: var(--space-1); border-radius: var(--radius-lg);
}
/* A 22px icon with --space-1 padding is a 30px target; touch gets --space-2 (38px). */
@media (hover: none) and (pointer: coarse) {
  .kwgt-chat-close { padding: var(--space-2); }
}
.kwgt-chat-close:hover { color: var(--brass); }
.kwgt-chat-header-info { flex: 1; }
.kwgt-chat-title { font-size: var(--text-body); line-height: var(--leading-snug); }
.kwgt-chat-sub { font-size: var(--text-xs); color: var(--brass-light); margin-top: var(--space-1); }
.kwgt-chat-header-spacer { width: var(--space-6); }

.kwgt-prechat { padding: var(--space-6) var(--space-5); display: flex; flex-direction: column; gap: var(--space-3); }
.kwgt-prechat-intro { color: var(--ivory-mute); font-size: var(--text-base); line-height: var(--leading-chat); margin-bottom: var(--space-2); }
/* Prechat fields and the composer use the site's form-field recipe (input,
   select, textarea above), so they get the same fill, focus ring and 16px touch
   size; the start button is a .btn. Only chat-specific layout is set here. */
.kwgt-start-btn { margin-top: var(--space-1); }
.kwgt-err { color: var(--conch); font-size: var(--text-xs); min-height: 0.5em; }

.kwgt-body { display: none; flex: 1; flex-direction: column; min-height: 0; }
.kwgt-messages { flex: 1; overflow-y: auto; padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); }
.kwgt-msg {
  max-width: 80%; padding: var(--space-3) var(--space-4); border-radius: var(--radius-xl);
  font-size: var(--text-base); line-height: var(--leading-chat); word-wrap: break-word; white-space: pre-wrap;
}
.kwgt-msg.visitor { align-self: flex-end; background: var(--gradient-brass-muted); color: var(--black-rich); border-bottom-right-radius: var(--radius-lg); }
.kwgt-msg.agent { align-self: flex-start; background: var(--charcoal-light); color: var(--ivory); border-bottom-left-radius: var(--radius-lg); }
/* A visitor message the server did not accept (js/main.js marks it). */
.kwgt-msg.failed { opacity: var(--opacity-soft); }
.kwgt-composer { display: flex; gap: var(--space-2); padding: var(--space-3); border-top: 1px solid var(--charcoal-line); }
/* One row tall (the global textarea minimum is for the quote form's notes). */
.kwgt-text { flex: 1; resize: none; min-height: var(--tap-min); max-height: 96px; }
/* Icon button in the btn-gold colours. */
.kwgt-send {
  width: var(--tap-min); border: none; border-radius: var(--radius); cursor: pointer;
  background: var(--brass); color: var(--black-rich); font-size: var(--text-md);
  transition: background var(--dur-base);
}
.kwgt-send:hover { background: var(--brass-light); }

.kwgt-toast {
  position: absolute; bottom: var(--chat-offset); right: 0; width: var(--chat-toast-w);
  background: var(--charcoal); border: 1px solid var(--brass-deep); border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4); box-shadow: var(--shadow-card); cursor: pointer;
  opacity: 0; visibility: hidden; transform: translateY(var(--enter-shift)); transition: opacity var(--dur-base), transform var(--dur-base), visibility var(--dur-base);
}
.kwgt-toast.show { opacity: 1; visibility: visible; transform: translateY(0); }
.kwgt-toast-text { color: var(--ivory); font-size: var(--text-base); margin-top: var(--space-1); }

/* On phones the floating circle becomes a full-width bar pinned to the bottom.
   A 60px circle at 24px insets blocked an 84x84 corner of the viewport above all
   content with nothing reserving space for it; a bar occupies a band that the page
   can actually pad for, and it carries a label instead of a bare icon. */
@media (max-width: 640px) {
  .kwgt-chat {
    left: 0;
    right: 0;
    bottom: 0;
  }
  .kwgt-toggle {
    width: 100%;
    height: auto;
    min-height: var(--chat-bar-h);
    border-radius: 0;
    gap: var(--space-3);
    padding: var(--space-4) var(--gutter);
    /* Clear of the home indicator on notched phones; resolves to 0 elsewhere. */
    padding-bottom: calc(var(--space-4) + env(safe-area-inset-bottom, 0px));
    box-shadow: var(--shadow-card);
  }
  .kwgt-toggle-label {
    display: inline;
    font-size: var(--text-base);
  }
  .kwgt-badge { position: static; margin-left: var(--space-2); }

  /* Reserve the band so the bar never covers the end of the page. */
  .site-footer { padding-bottom: var(--space-20); }

  /* The toast belongs above the bar, not over the corner. */
  .kwgt-toast {
    width: auto;
    left: var(--space-4);
    right: var(--space-4);
    bottom: calc(100% + var(--space-2));
  }
}

@media (max-width: 480px) {
  body.kwgt-open .kwgt-chat-window.open {
    position: fixed; inset: 0; width: 100%; height: 100%; max-width: 100%; max-height: 100%; border-radius: 0;
  }


  /* A fixed 280px toast is ~78% of a 360px viewport. */
  .kwgt-toast {
    width: auto;
    max-width: calc(100vw - var(--space-8));
    bottom: var(--space-16);
  }
}

/* ===== SCROLL REVEAL (classes toggled by js/main.js) ===== */
.reveal {
  opacity: 0;
  transform: translateY(var(--reveal-shift));
  transition: opacity var(--dur-slower) var(--ease-standard), transform var(--dur-slower) var(--ease-standard);
}
.reveal.in {
  opacity: 1;
  transform: translateY(0);
}

/* ============================================================
   ACCESSIBILITY BASELINE
   ============================================================ */
/* Skip link — visually offscreen until keyboard-focused */
.skip-link {
  position: absolute;
  top: 0;
  left: 0;
  z-index: var(--z-skip);
  padding: var(--space-3) var(--space-5);
  background: var(--brass);
  color: var(--black-rich);
  transform: translateY(-110%);
  transition: transform var(--dur-fast);
}
.skip-link:focus { transform: translateY(0); }

/* Screen-reader-only text */
.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;
}

/* NOTE ON PLACEMENT: this section sits after every component rule on purpose. A
   media query adds no specificity, so an equal-specificity rule declared later in
   the file beats it at every width. .contact-layout and .service-detail-inner are
   defined further down than this block used to be, which silently killed their
   collapse-to-one-column rules and left both layouts two-column on phones. Keep
   mobile structure last. (scratchpad deadoverride.mjs detects regressions.)
*/
/* ============================================================
   MOBILE STRUCTURE
   Reordering, not resizing: on a phone the page order itself changes so the
   booking action comes first, rather than everything being made smaller to fit.
   ============================================================ */
@media (max-width: 880px) {
  /* Home page only. `main` carries no page class, so it is identified by the hero
     it uniquely contains; where :has() is unsupported the rule is simply skipped
     and the DOM order stands. Flex is a no-op for ordering on every other page
     because unset children all share order 0 and stay in source order. */
  main:has(> .hero) {
    display: flex;
    flex-direction: column;
  }
  /* The closing CTA carries the compact quote form and the call/email block, and
     it sat at the very bottom, six sections and a full-height hero below the fold.
     On a phone it moves directly under the hero, so the booking action is the first
     thing after the headline instead of the last thing on the page. The remaining
     sections keep their source order (fleet, about, services, testimonials). */
  main:has(> .hero) > .hero { order: -2; }
  main:has(> .hero) > .cta-closing { order: -1; }

  /* Footer: contact details first, then company, then the services list (collapsed),
     with the brand block last before the legal row. Reordered rather than
     compressed -- the phone-relevant information comes first instead of after
     thirteen links. */
  .footer-top { display: flex; flex-direction: column; gap: var(--space-10); }
  .footer-top > .footer-col--contact  { order: 1; }
  .footer-top > .footer-col--company  { order: 2; }
  .footer-top > .footer-col--services { order: 3; }
  .footer-top > .footer-brand         { order: 4; }

  /* Collapsed by default here (js/main.js closes it below the breakpoint), so the
     summary becomes a real control and needs a marker and a tap target. */
  .footer-details > summary {
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: var(--tap-min);
  }
  .footer-details > summary::after {
    content: '\002B';
    font-family: var(--font-label);
    font-size: var(--text-lg);
    color: var(--brass);
    line-height: var(--leading-none);
  }
  .footer-details[open] > summary::after { content: '\2212'; }
  .footer-details > summary .footer-heading { margin-bottom: 0; }

  /* Media card (vehicles, services): a tall stack (4:3 image, then a padded block of
     tag, name, copy and CTA) runs ~540px per card on a 375px screen, so the fleet
     page was ~2,100px of scrolling. Restructured into a media object: a proportional
     thumbnail beside the tag and name, with the description and CTA spanning the full
     width beneath. `display: contents` promotes .card-body's children to grid items
     of the card, so the same content is rearranged, not shrunk. */
  .card--media {
    display: grid;
    grid-template-columns: 40% 1fr;
    column-gap: var(--space-5);
    row-gap: var(--space-4);
    padding: var(--space-5);
    align-items: start;
  }
  .card--media .card-body  { display: contents; }
  .card--media .card-media {
    grid-column: 1;
    grid-row: 1 / span 2;
    border-radius: var(--radius);
  }
  .card--media .card-tag   { grid-column: 2; grid-row: 1; margin-bottom: 0; }
  .card--media .card-title { grid-column: 2; grid-row: 2; }
  .card--media .card-text  { grid-column: 1 / -1; grid-row: 3; margin-bottom: 0; }
  .card--media .card-meta  { grid-column: 1 / -1; grid-row: 4; margin-bottom: 0; }
  .card--media .card-cta   { grid-column: 1 / -1; grid-row: 5; justify-self: start; }

  .nav-menu { display: none; }
  .hamburger { display: flex; }
  /* Every 2-col content/media layout collapses with the nav, per tokens.md §6.
     .about-inner and .cta-content moved here from 960 (2026-09-07) so the site no
     longer has two collapse points; .footer-top stays at 960 because a 4-track
     grid changing count is what 960 is for. */
  .about-inner,
  .cta-content {
    grid-template-columns: 1fr;
    gap: var(--space-12);
  }
  .service-detail-inner { grid-template-columns: 1fr; }
  .service-detail-img { order: -1; }
  .contact-layout { grid-template-columns: 1fr; }
  .contact-layout .booking-form { order: -1; }

  /* Let the long strings break rather than push the page sideways: the 38-char
     email is the worst case. `break-word`, not `anywhere`/`break-all` — those
     change min-content and so would change `fr` track resolution. Scoped to the
     mobile branch because the email may already be at the edge of its desktop
     footer column, and widening that column is not this change's business. */
  .footer-col a,
  .cta-email,
  .contact-detail a,
  .breadcrumb {
    overflow-wrap: break-word;
  }

  /* The phone and email on the contact page are the primary conversion actions
     there and were ~29px tall. Padding rather than min-height so a wrapped email
     does not get a hit box taller than its text. */
  .contact-detail a {
    display: inline-block;
    padding: var(--space-2) 0;
  }

  /* Breadcrumb links were ~20px tall. WCAG 2.5.8's 24px is the right bar here
     rather than 44: the trail is a redundant path (the nav and drawer expose the
     same links), and 44px hit boxes on inline links that wrap would overlap each
     other between lines. */
  .breadcrumb a {
    display: inline-block;
    padding: var(--space-1) 0;
  }

  /* Same reasoning for the per-card CTAs, which were ~24px. */
  .card-cta,
  .inline-cta {
    display: inline-block;
    padding: var(--space-2) 0;
  }
}
@media (min-width: 881px) { .mobile-menu { display: none; } }


/* ============================================================
   TOUCH FEEDBACK
   ============================================================ */

/* Press feedback. Touch has no hover, so without an :active state a tap on a
   card or button gives no acknowledgement at all until the next page paints. */
.btn:active,
.card--link:active,
.kwgt-toggle:active {
  transform: translateY(var(--press));
}

a, button, summary, input, select, textarea {
  -webkit-tap-highlight-color: var(--brass-overlay-subtle);
}

/* iOS keeps :hover applied after a tap until the next tap elsewhere, so the lift
   and fill states stick and read as "pressed" or "disabled". Neutralize just those
   two families on touch and let :active above carry the feedback. A pointer device
   never matches this query, so desktop is untouched. */
@media (hover: none) {
  .btn-gold:hover,
  .card--link:hover,
  .cta-phone:hover,
  .kwgt-toggle:hover {
    transform: none;
  }
  /* The card photo's zoom is a separate transform and stays zoomed after a tap if
     it isn't neutralized alongside the card lift. */
  .card--link:hover .card-media img {
    transform: none;
  }
  .btn-outline:hover {
    background: transparent;
    color: var(--white);
  }
  /* These reveal their underline only on hover, so on touch they are brass caps
     text with no link affordance at all. Give them a resting one instead. */
  .card-cta,
  .inline-cta {
    border-bottom-color: var(--brass-overlay-strong);
  }
}

/* Keyboard focus — a visible brass ring on anything focusable.
   :focus-visible fires for keyboard navigation, not mouse clicks,
   so pointer users never see it. Form fields keep their existing
   brass :focus border + glow on top of this. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: var(--focus-offset);
}

/* Honor the OS-level reduced-motion preference: collapse transitions
   and animations to imperceptible durations instead of removing them,
   so JS that waits on transitionend/animationend still fires. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}
