/* =========================================================================
   13 Melbourne Taxi
   Design system and components.

   Direction: "the meter". Black and orange straight off the logo artwork.
   The signature is the live fare meter in the booking card, so everything
   around it stays quiet and lets that one element carry the page.

   Palette is fully tokenised: the :root block is the only place colour is
   declared.
   ========================================================================= */

/* ---------- Tokens ---------- */

:root {
	/* Ink. Taken from the logo, which sets its orange on true black. A blue
	   tinted dark would fight the mark, so the neutrals stay neutral. */
	--ink:        #0B0B0D;
	--ink-soft:   #17171B;
	--ink-line:   #2B2B31;
	--ink-muted:  #9C9CA6;

	/* Paper. A hair off white so large light areas do not glare at 4am. */
	--paper:      #F6F6F4;
	--surface:    #FFFFFF;
	--line:       #E3E2DE;
	--line-soft:  #EFEEEB;
	--text:       #131316;
	--muted:      #5B5B66;

	/* Brand orange, sampled from the logo artwork. The only accent that
	   shouts, and always paired with black the way the logo pairs them. */
	--orange:      #FC7D03;
	--orange-hi:   #FF9526; /* Hover lift. */

	/* Vacant. The green light on a Melbourne roof means the cab is free.
	   Used only for live availability, never as decoration. */
	--vacant:     #12A15F;
	--alert:      #C4321F;

	/* Type */
	--display: "Archivo", "Helvetica Neue", Arial, sans-serif;
	--body:    "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

	/* Fluid type scale */
	--t-xs:   0.8rem;
	--t-sm:   0.875rem;
	--t-base: 1rem;
	--t-lg:   1.125rem;
	/* Scaled down across the board, H1 most of all: proportions between the
	   tiers are kept the same, just the whole hierarchy sits smaller. */
	--t-xl:   clamp(1.15rem, 1.02rem + 0.5vw, 1.35rem);
	--t-2xl:  clamp(1.3rem, 1.1rem + 0.9vw, 1.75rem);
	--t-3xl:  clamp(1.7rem, 1.4rem + 1.5vw, 2.5rem);
	--t-4xl:  clamp(2.1rem, 1.65rem + 2.4vw, 3.4rem);

	/* Space */
	--s-1: 4px;   --s-2: 8px;   --s-3: 12px;  --s-4: 16px;
	--s-5: 24px;  --s-6: 32px;  --s-7: 48px;  --s-8: 64px;
	--s-9: 96px;  --s-10: 128px;

	--radius:    14px;
	--radius-sm: 9px;
	--radius-lg: 22px;

	--shadow-sm: 0 1px 2px rgba(11,11,13,.06), 0 2px 8px rgba(11,11,13,.05);
	--shadow:    0 4px 12px rgba(11,11,13,.08), 0 16px 40px rgba(11,11,13,.08);
	--shadow-lg: 0 8px 24px rgba(11,11,13,.12), 0 32px 64px rgba(11,11,13,.14);

	--wrap: 1200px;
	--ease: cubic-bezier(.22,.61,.36,1);
}

/* ---------- Reset ---------- */

*, *::before, *::after { box-sizing: border-box; }

/* A component display rule must never beat the hidden attribute. */
[hidden] { display: none !important; }

/* overflow-x here too, not just on body: a position:fixed element (the
   sticky action bar) is laid out against the viewport, not against body, so
   a body-only rule does not stop it from widening the page's own scrollable
   range. That is what let a real device's font metrics push the action bar
   a hair past 100% and leave the page shifted after the keyboard opened,
   even though nothing here ever showed a visible overflow in testing. */
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; overflow-x: hidden; }

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	*, *::before, *::after {
		animation-duration: .01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: .01ms !important;
	}
}

body {
	margin: 0;
	background: var(--paper);
	color: var(--text);
	font-family: var(--body);
	font-size: var(--t-base);
	line-height: 1.65;
	-webkit-font-smoothing: antialiased;
	overflow-x: hidden;
}

img, svg, video { max-width: 100%; height: auto; display: block; }

h1, h2, h3, h4 {
	font-family: var(--display);
	font-weight: 700;
	line-height: 1.1;
	letter-spacing: -0.02em;
	margin: 0 0 var(--s-4);
	color: var(--text);
	text-wrap: balance;
	text-transform: capitalize;
}

h1 { font-size: var(--t-4xl); letter-spacing: -0.035em; }
h2 { font-size: var(--t-3xl); letter-spacing: -0.03em; }
h3 { font-size: var(--t-xl); }

p { margin: 0 0 var(--s-4); text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

a { color: inherit; }

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
	outline: 3px solid var(--orange);
	outline-offset: 2px;
	border-radius: 4px;
}

.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;
}

.skip-link {
	position: absolute; left: 0; top: 0; z-index: 999;
	transform: translateY(-120%);
	background: var(--ink); color: #fff; padding: var(--s-3) var(--s-5);
	font-weight: 600;
}
.skip-link:focus { transform: translateY(0); }

/* ---------- Layout ---------- */

.wrap {
	width: 100%;
	max-width: var(--wrap);
	margin-inline: auto;
	padding-inline: var(--s-5);
}

.section { padding-block: clamp(48px, 7vw, 96px); }
.section--tight { padding-block: clamp(36px, 5vw, 64px); }
.section--ink { background: var(--ink); color: #fff; }
.section--ink h2, .section--ink h3 { color: #fff; }

.section__head { max-width: 62ch; margin-bottom: var(--s-6); }
.section__head--center { margin-inline: auto; text-align: center; }

.eyebrow {
	font-family: var(--display);
	font-size: var(--t-xs);
	font-weight: 700;
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--orange);
	margin: 0 0 var(--s-3);
	display: block;
}
.section--ink .eyebrow { color: var(--orange); }

.lede { font-size: var(--t-lg); color: var(--muted); }
.section--ink .lede { color: var(--ink-muted); }

/* ---------- Checker rule ----------
   The taxi checker, used structurally rather than decoratively: it marks the
   seam between sections. Never used as background texture. */

.checker {
	height: 20px;
	width: 100%;
	background-image:
		linear-gradient(45deg, var(--ink) 25%, transparent 25%, transparent 75%, var(--ink) 75%),
		linear-gradient(45deg, var(--ink) 25%, transparent 25%, transparent 75%, var(--ink) 75%);
	background-size: 20px 20px;
	background-position: 0 0, 10px 10px;
	background-color: var(--orange);
}
.checker--thin { height: 12px; background-size: 12px 12px; background-position: 0 0, 6px 6px; }

/* ---------- Buttons ---------- */

.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--s-2);
	font-family: var(--display);
	font-weight: 700;
	font-size: var(--t-base);
	letter-spacing: 0;
	word-spacing: .06em;
	padding: 14px 24px;
	border-radius: var(--radius-sm);
	border: 2px solid transparent;
	cursor: pointer;
	text-decoration: none;
	text-transform: capitalize;
	transition: transform .15s var(--ease), background-color .15s var(--ease), border-color .15s var(--ease);
	line-height: 1.2;
	text-align: center;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

.btn--primary { background: var(--orange); color: #fff; }
.btn--primary:hover { background: var(--orange-hi); }

.btn--ink { background: var(--ink); color: #fff; }
.btn--ink:hover { background: var(--ink-soft); }

.btn--ghost { background: transparent; color: var(--text); border-color: var(--line); }
.btn--ghost:hover { border-color: var(--text); }

.section--ink .btn--ghost { color: #fff; border-color: var(--ink-line); }
.section--ink .btn--ghost:hover { border-color: #fff; }

/* Pre footer close section. Orange, not black, per the client. Body copy
   stays dark for genuine readability (a full sentence needs more contrast
   than a heading can get away with); the heading follows the same white on
   orange the client chose for buttons elsewhere. The primary button switches
   to .btn--ink here specifically, since an orange button would disappear on
   an orange section. */
.section--orange { background: var(--orange); color: var(--ink); }
.section--orange h2, .section--orange h3 { color: #fff; }
.section--orange .lede { color: var(--ink); }
/* Solid white, not just an outline: next to the solid black primary button,
   a thin dark-on-orange outline read as the weaker, secondary option even
   though calling and booking online are equally valid choices here. Matching
   solid weight on both puts them on equal footing. */
.section--orange .btn--ghost {
	background: #fff;
	color: var(--ink);
	border-color: #fff;
}
.section--orange .btn--ghost:hover { background: var(--paper); border-color: var(--paper); }

.btn--lg { padding: 17px 30px; font-size: var(--t-lg); }
.btn--sm { padding: 10px 16px; font-size: var(--t-sm); }
.btn--block { width: 100%; min-height: 48px; }

/* ---------- Header ---------- */

.site-header {
	position: sticky;
	top: 0;
	z-index: 100;
	background: var(--ink);
	color: #fff;
}

.site-header__bar {
	display: flex;
	align-items: center;
	gap: var(--s-5);
	min-height: 72px;
}

/* Brand lockup. Two artwork variants, one for dark surfaces and one for
   light, each with the outer background already knocked out. */
.brand { display: inline-flex; align-items: center; text-decoration: none; color: #fff; flex-shrink: 0; }
.brand img { height: 42px; width: auto; }
@media (max-width: 620px) { .brand img { height: 34px; } }
.brand--sm img { height: 34px; }

.nav { margin-left: auto; }
.nav__list { display: flex; align-items: center; gap: var(--s-5); list-style: none; margin: 0; padding: 0; }
.nav__list a {
	text-decoration: none;
	font-size: var(--t-sm);
	font-weight: 500;
	color: #fff;
	opacity: .82;
	white-space: nowrap;
	text-transform: capitalize;
	transition: opacity .15s var(--ease);
}
.nav__list a:hover { opacity: 1; }

.header__actions { display: flex; align-items: center; gap: var(--s-3); flex-shrink: 0; }

/* Dropdowns. Opened on hover for a mouse and on click for everything else, so
   the same markup serves both without a hover trap on touch. Kept in the DOM
   rather than built on open, so the links are crawlable. */
.nav__has-sub { position: relative; }
.nav__subtoggle {
	display: inline-flex; align-items: center; gap: 5px;
	background: none; border: 0; padding: 0; cursor: pointer;
	font-family: inherit; font-size: var(--t-sm); font-weight: 500;
	color: #fff; opacity: .82; white-space: nowrap;
	text-transform: capitalize;
	transition: opacity .15s var(--ease);
}
.nav__subtoggle:hover { opacity: 1; }
.nav__subtoggle svg { width: 15px; height: 15px; transition: transform .18s var(--ease); }
.nav__has-sub:hover .nav__subtoggle svg,
.nav__subtoggle[aria-expanded="true"] svg { transform: rotate(180deg); }

.nav__sub {
	position: absolute; top: calc(100% + 14px); left: 50%;
	transform: translateX(-50%) translateY(-6px);
	min-width: 232px;
	list-style: none; margin: 0; padding: 8px;
	background: var(--ink-2, #16161A);
	border: 1px solid var(--ink-line);
	border-radius: var(--radius-sm);
	box-shadow: 0 18px 40px rgba(0,0,0,.45);
	opacity: 0; visibility: hidden; pointer-events: none;
	transition: opacity .16s var(--ease), transform .16s var(--ease), visibility .16s;
	z-index: 60;
}
/* A gap between the button and the panel would drop the hover, so the panel
   reaches back up to the bar with a transparent pad. */
.nav__sub::before { content: ""; position: absolute; inset: -14px 0 100% 0; }
.nav__has-sub:hover .nav__sub,
.nav__has-sub:focus-within .nav__sub,
.nav__subtoggle[aria-expanded="true"] + .nav__sub {
	opacity: 1; visibility: visible; pointer-events: auto;
	transform: translateX(-50%) translateY(0);
}
.nav__sub a {
	display: block; padding: 9px 12px; border-radius: 7px;
	opacity: .85; white-space: normal;
	text-transform: capitalize;
}
.nav__sub a:hover { opacity: 1; background: rgba(255,255,255,.06); }



/* Phone is a first class action, not a footer detail. Most taxi bookings
   still start with a call. */
.btn--footer-whatsapp { background: #25D366; color: #fff; }
.btn--footer-whatsapp:hover { background: #1EBE5A; }
.callnow { display: inline-flex; align-items: center; gap: 9px; text-decoration: none; color: #fff; }
.callnow__icon {
	width: 38px; height: 38px; border-radius: 50%;
	background: rgba(252,125,3,.14);
	border: 1px solid rgba(252,125,3,.3);
	display: grid; place-items: center; color: var(--orange); flex-shrink: 0;
}
.callnow__txt { display: flex; flex-direction: column; line-height: 1.15; }
.callnow__txt small { font-size: 11px; color: var(--ink-muted); letter-spacing: .06em; text-transform: uppercase; }
.callnow__txt b { font-family: var(--display); font-size: 15.5px; font-weight: 700; font-variant-numeric: tabular-nums; }

.navtoggle {
	display: none;
	background: transparent; border: 1px solid var(--ink-line);
	color: #fff; width: 44px; height: 44px; border-radius: 10px;
	cursor: pointer; align-items: center; justify-content: center;
}

/* ---------- Hero ---------- */

.hero {
	background: var(--ink);
	color: #fff;
	position: relative;
	overflow: hidden;
	padding-block: clamp(36px, 5vw, 68px) clamp(48px, 7vw, 88px);
}

/* A single soft amber wash, like a streetlight. One atmospheric move, not a
   pile of gradients. */
.hero::before {
	content: "";
	position: absolute;
	top: -20%; right: -10%;
	width: 720px; height: 720px;
	background: radial-gradient(circle, rgba(252,125,3,.16) 0%, transparent 62%);
	pointer-events: none;
}

.hero__grid {
	position: relative;
	display: grid;
	grid-template-columns: 1fr minmax(400px, 480px);
	gap: clamp(32px, 5vw, 72px);
	align-items: start;
}

.hero__copy { padding-top: var(--s-5); }

.hero h1 { color: #fff; margin-bottom: var(--s-5); }
.hero h1 em {
	font-style: normal;
	color: var(--orange);
}

.hero__lede { font-size: var(--t-lg); color: var(--ink-muted); max-width: 46ch; margin-bottom: var(--s-6); }

/* Trust row. Facts only, and only facts we can stand behind. White text: only
   ever used on a dark hero, never on the plain page background. */
.trustrow { display: flex; flex-wrap: wrap; gap: var(--s-5) var(--s-6); padding: 0; margin: 0; list-style: none; }
.trustrow li { display: flex; align-items: center; gap: 10px; font-size: var(--t-sm); color: #fff; }
.trustrow svg { color: var(--orange); flex-shrink: 0; }

/* Same short icon led line, for a sidebar sitting on the plain page
   background rather than a dark hero, so it needs the page's own text
   colour instead of trustrow's white. */
.pointlist { display: grid; gap: 14px; padding: 0; margin: 0 0 20px; list-style: none; }
.pointlist li { display: flex; align-items: center; gap: 10px; font-size: var(--t-sm); color: var(--text); }
.pointlist svg { color: var(--orange); flex-shrink: 0; }

/* The Cabcharge badge sits top-left, clear of the card-and-terminal action
   the photo is actually about, and scales down with the photo instead of
   staying a fixed size that overwhelms it once the photo goes short on
   mobile. */
.cabchargephoto { position: relative; }
.cabchargephoto__badge {
	position: absolute;
	top: clamp(12px, 3vw, 18px);
	left: clamp(12px, 3vw, 18px);
	background: #fff;
	border-radius: var(--radius-sm);
	padding: clamp(10px, 2.2vw, 16px) clamp(16px, 3.5vw, 24px);
	box-shadow: 0 4px 14px rgba(11,11,13,.18);
}
.cabchargephoto__badge img { display: block; height: clamp(24px, 6vw, 36px); width: auto; }

.tacphoto { position: relative; }
.tacphoto__badge {
	position: absolute;
	top: clamp(12px, 3vw, 18px);
	left: clamp(12px, 3vw, 18px);
	background: var(--ink-2, #16161A);
	border-radius: var(--radius-sm);
	padding: clamp(10px, 2.2vw, 16px) clamp(16px, 3.5vw, 24px);
	box-shadow: 0 4px 14px rgba(11,11,13,.18);
}
.tacphoto__badge img { display: block; height: clamp(22px, 5.5vw, 32px); width: auto; }

.livedot {
	width: 8px; height: 8px; border-radius: 50%;
	background: var(--vacant);
	box-shadow: 0 0 0 4px rgba(18,161,95,.18);
	flex-shrink: 0;
}
@media (prefers-reduced-motion: no-preference) {
	.livedot { animation: pulse 2.4s var(--ease) infinite; }
	@keyframes pulse {
		0%, 100% { box-shadow: 0 0 0 4px rgba(18,161,95,.18); }
		50%      { box-shadow: 0 0 0 8px rgba(18,161,95,.06); }
	}
}

/* ---------- Booking card ---------- */

.bookcard {
	background: var(--surface);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-lg);
	overflow: hidden;
	color: var(--text);
}
/* On the booking page the form is the page, so it does not need a card around
   it. The panel treatment is for the hero, where the form is an object sitting
   on a photo backdrop and has to lift off it. */
.bookcard--plain {
	background: transparent;
	border-radius: 0;
	box-shadow: none;
	overflow: visible;
}
.bookcard--plain .bookcard__body { padding: 0; }

/* Now or later. A segmented control rather than a tab strip: this sits inside
   the form as a choice between two states, not as navigation between two
   panes, and the pill makes the selected one unmistakable at a glance. */
.bookcard__tabs {
	display: flex;
	gap: 4px;
	padding: 4px;
	background: var(--surface);
	border: 1.5px solid var(--line);
	border-radius: 11px;
}
.bookcard__tab {
	flex: 1;
	appearance: none;
	background: transparent;
	border: 0;
	border-radius: 8px;
	padding: 9px 10px;
	min-height: 44px;
	font-family: var(--display);
	font-weight: 600;
	font-size: var(--t-sm);
	color: var(--muted);
	cursor: pointer;
	/* Deliberately allowed to wrap. "As soon as possible" does not fit on one
	   line inside the card at 320px, and nowrap pushed the whole page 12px
	   wide rather than taking a second line. */
	line-height: 1.25;
	transition: background-color .16s var(--ease), color .16s var(--ease), box-shadow .16s var(--ease);
}
.bookcard__tab:hover { color: var(--text); }
.bookcard__tab[aria-selected="true"] {
	background: var(--orange);
	color: #fff;
	font-weight: 700;
	box-shadow: 0 1px 3px rgba(11,11,13,.12);
}
.bookcard__tab:focus-visible { outline: 2px solid var(--orange); outline-offset: 1px; }

.bookcard__body { padding: var(--s-4); }

/* Address suggestions. Anchored to the field rather than the input, so it
   clears the locate button on the pickup row too. */
.acmenu {
	position: absolute;
	top: 100%; left: 0; right: 0;
	z-index: 40;
	margin: 4px 0 0;
	padding: 5px;
	list-style: none;
	max-height: 264px;
	overflow-y: auto;
	background: var(--paper);
	border: 1.5px solid var(--line);
	border-radius: 10px;
	box-shadow: 0 14px 34px rgba(11,11,13,.16);
}
.acmenu[hidden] { display: none !important; }
.acmenu--up {
	top: auto;
	bottom: 100%;
	margin: 0 0 4px;
	box-shadow: 0 -14px 34px rgba(11,11,13,.16);
}
.acitem {
	padding: 11px 12px;
	min-height: 44px;
	display: flex;
	align-items: center;
	border-radius: 7px;
	font-size: var(--t-sm);
	color: var(--text);
	cursor: pointer;
}
.acitem:hover,
.acitem.is-active { background: rgba(252,125,3,.12); }

/* ---------- Fields ---------- */

.field { margin-bottom: var(--s-3); position: relative; }
.field:last-child { margin-bottom: 0; }

.field > label,
.fieldset > legend {
	display: block;
	font-size: var(--t-sm);
	font-weight: 600;
	margin-bottom: 5px;
	color: var(--text);
	text-transform: capitalize;
}
.field__optional { font-weight: 400; color: var(--muted); }



.field select { text-transform: capitalize; }
.field select option { text-transform: capitalize; }

.field input[type="text"],
.field input[type="tel"],
.field input[type="email"],
.field input[type="date"],
.field input[type="time"],
.field input[type="number"],
.field select,
.field textarea {
	width: 100%;
	font-family: var(--body);
	font-size: var(--t-base);
	/* 16px is the floor: anything smaller and iOS Safari zooms the page on
	   focus. The padding takes the height instead. min-height is the real
	   guarantee though: padding alone measured 41px in practice, 3px under
	   the touch target floor, since form control line-height varies by
	   browser rather than following the padding math exactly. */
	padding: 10px 13px;
	min-height: 44px;
	border: 1.5px solid var(--line);
	border-radius: var(--radius-sm);
	background: var(--surface);
	color: var(--text);
	transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
.field input:hover, .field select:hover { border-color: #CFC9BB; }
.field input:focus, .field select:focus, .field textarea:focus {
	outline: none;
	border-color: var(--orange);
	box-shadow: 0 0 0 3px rgba(252,125,3,.22);
}

/* Country code and mobile number as one connected control, the standard
   phone-input pattern. The two pieces sit flush (no gap, no border between
   them, only the outer edges rounded) so they read as a single field despite
   being two form elements. Placed after the global .field input/select rule,
   and repeats its hover and focus states with 'none', because both blocks
   match input[type="tel"] and select with the same specificity: without this,
   the global rule's hover and focus borders win by source order and stack a
   second border and a second focus ring on top of the wrapper's own. */
.phonegroup {
	display: flex;
	border: 1.5px solid var(--line);
	border-radius: var(--radius-sm);
	background: var(--surface);
	transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
.phonegroup:hover { border-color: #CFC9BB; }
.phonegroup:focus-within {
	border-color: var(--orange);
	box-shadow: 0 0 0 3px rgba(252,125,3,.15);
}
.phonegroup input[type="tel"] {
	flex: 1;
	min-width: 0;
	border: 0;
	border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.phonegroup input[type="tel"]:hover,
.phonegroup input[type="tel"]:focus {
	border: 0;
	box-shadow: none;
}
/* The sitewide :focus-visible rule already outlines whichever piece is
   actually tabbed to; nothing here needs to fight or replace it. */

/* Country code picker: a real listbox built by hand, not a native <select>.
   Flag emoji inside a native select's option list render as blank boxes on
   Windows (regional indicator pairs are drawn as two letter codes there by
   design, not flag glyphs) and on any environment without a colour emoji
   font, confirmed missing even outside Windows during testing. Real SVG
   flags here render identically everywhere since nothing depends on the
   OS's own emoji support. */
.ccpick { position: relative; }
.ccpick__btn {
	flex: 0 0 auto;
	display: flex; align-items: center; gap: 6px;
	border: 0;
	border-right: 1.5px solid var(--line);
	border-radius: var(--radius-sm) 0 0 var(--radius-sm);
	background: transparent;
	padding: 10px 10px 10px 12px;
	font-family: var(--body);
	font-size: var(--t-base);
	color: var(--text);
	cursor: pointer;
}
.ccpick__btn:hover, .ccpick__btn[aria-expanded="true"] { background: var(--paper); }
.ccpick__btn img { width: 20px; height: 15px; border-radius: 2px; flex-shrink: 0; object-fit: cover; }
.ccpick__btn svg { width: 14px; height: 14px; flex-shrink: 0; color: var(--muted); }
.ccpick__menu {
	position: absolute;
	top: 100%; left: 0;
	z-index: 40;
	margin: 4px 0 0;
	padding: 5px;
	list-style: none;
	width: 260px;
	max-width: 90vw;
	max-height: 280px;
	overflow-y: auto;
	background: var(--paper);
	border: 1.5px solid var(--line);
	border-radius: 10px;
	box-shadow: 0 14px 34px rgba(11,11,13,.16);
}
.ccpick__menu[hidden] { display: none !important; }
.ccpick__item {
	display: flex; align-items: center; gap: 10px;
	padding: 9px 10px;
	min-height: 44px;
	border-radius: 7px;
	font-size: var(--t-sm);
	color: var(--text);
	cursor: pointer;
}
.ccpick__item img { width: 20px; height: 15px; border-radius: 2px; flex-shrink: 0; object-fit: cover; }
.ccpick__name { flex: 1; min-width: 0; }
.ccpick__dial { color: var(--muted); flex-shrink: 0; }
.ccpick__item:hover, .ccpick__item.is-active { background: rgba(252,125,3,.12); }
.ccpick__item[aria-selected="true"] { font-weight: 600; }


.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-3); }
/* A date and its time belong side by side. They read as one answer, and both
   inputs are narrow enough to hold two columns even on the smallest phone,
   unlike the name and phone pair which does stack. */
.field-row--split { grid-template-columns: 1fr 1fr; }
/* Grid children default to min-width:auto, and a native date input reports a
   wider intrinsic width than a time input, so 1fr 1fr silently comes out
   uneven. This makes the two halves actually equal. */
.field-row--split > .field { min-width: 0; }
.field-row--split input { width: 100%; }

.field__with-btn { position: relative; }
.field__with-btn input { padding-right: 46px; }
.locate {
	position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
	width: 34px; height: 34px; border-radius: 50%;
	background: rgba(252,125,3,.1); border: 0;
	color: var(--orange); cursor: pointer;
	display: grid; place-items: center;
}
.locate:hover { background: rgba(252,125,3,.18); }
.locate:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }

/* A live pulse reads as "this finds you", the way a map's blue dot does.
   Two rings expand and fade behind the pin so it doesn't look like it is
   simply blinking on and off, which reads as an error state, not a location
   button. Runs continuously and costs nothing while idle. */
.locate::before,
.locate::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	background: var(--orange);
	opacity: 0;
	animation: mt13-locate-pulse 2.2s ease-out infinite;
	pointer-events: none;
}
.locate::after { animation-delay: 1.1s; }
@keyframes mt13-locate-pulse {
	0%   { transform: scale(.65); opacity: .55; }
	70%  { transform: scale(1.55); opacity: 0; }
	100% { transform: scale(1.55); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
	.locate::before, .locate::after { animation: none; content: none; }
}

/* Mid fetch: the rings stop (a spinner is the honest state for "working",
   a pulse implies "idle, tap me") and the icon itself pulses in place. */
.locate:disabled {
	cursor: wait;
	opacity: .75;
}
.locate:disabled::before,
.locate:disabled::after { animation: none; content: none; }
.locate:disabled svg { animation: mt13-locate-spin 1s linear infinite; }
@keyframes mt13-locate-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
	.locate:disabled svg { animation: none; }
}

/* Found: a brief solid flash confirms the tap worked, distinct from the
   ongoing idle pulse. */
.locate.is-done {
	background: var(--orange);
	color: #fff;
	animation: mt13-locate-found .5s var(--ease);
}
@keyframes mt13-locate-found {
	0% { transform: translateY(-50%) scale(1); }
	40% { transform: translateY(-50%) scale(1.18); }
	100% { transform: translateY(-50%) scale(1); }
}

/* ---------- The meter ----------
   The signature. A real taxi meter reads out in tabular figures and only ever
   moves up. This does the same as the trip takes shape, which is the whole
   point: the passenger sees the price before they commit, not after. */

.meter {
	margin-top: var(--s-3);
	background: var(--ink);
	border-radius: var(--radius);
	padding: var(--s-3) var(--s-4);
	color: #fff;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--s-4);
	position: relative;
	overflow: hidden;
}
.meter::after {
	content: "";
	position: absolute; inset: 0;
	background: radial-gradient(circle at 88% 50%, rgba(252,125,3,.18) 0%, transparent 58%);
	pointer-events: none;
}

/* The booking form's meter is a <details> now, so the card itself has to
   stack (summary, then the breakdown below it) rather than stay a flex row;
   .meter__summary carries the exact row layout the plain div version above
   still uses directly, so the fleet page's own static .meter (no accordion,
   no summary) is untouched. */
.meter.js-meter {
	display: block;
	padding: 0;
}
.meter__summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--s-4);
	padding: var(--s-3) var(--s-4);
	cursor: pointer;
	list-style: none;
}
.meter__summary::-webkit-details-marker { display: none; }
.meter__chevron {
	position: relative; z-index: 1;
	flex-shrink: 0;
	width: 9px; height: 9px;
	border-right: 2px solid rgba(255,255,255,.5);
	border-bottom: 2px solid rgba(255,255,255,.5);
	transform: rotate(45deg);
	transition: transform .2s var(--ease);
}
.meter[open] .meter__chevron { transform: rotate(-135deg); }
/* Nothing to expand yet: the chevron only implies content once there is a
   price to check, not on an empty card before both addresses are typed. */
.meter:has(.farebreak[hidden]) .meter__summary { cursor: default; }
.meter:has(.farebreak[hidden]) .meter__chevron { display: none; }

/* The itemised rows, now inside the dark card instead of sitting on the
   page background underneath it: .farebreak's own colours are the light
   background version still used by the fares page estimator, so this
   overrides just the piece that changes for a dark card rather than
   touching the shared rule both places rely on. */
.meter .farebreak {
	position: relative; z-index: 1;
	margin-top: 0;
	padding: 0 var(--s-4) var(--s-3);
	border-top: 1px solid rgba(255,255,255,.14);
}
.meter .farebreak__row {
	color: rgba(255,255,255,.7);
	border-bottom-color: rgba(255,255,255,.12);
}
.meter .farebreak__row b { color: #fff; }
.meter .farebreak__row--head {
	color: #fff;
	border-top-color: rgba(255,255,255,.14);
}

.meter__label { position: relative; z-index: 1; }
.meter__label small {
	display: block;
	font-size: 11px;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--ink-muted);
	margin-bottom: 3px;
}
.meter__label span { font-size: var(--t-sm); color: #fff; }

.meter__value {
	position: relative; z-index: 1;
	font-family: var(--display);
	font-weight: 800;
	font-size: clamp(1.9rem, 1.5rem + 1.6vw, 2.5rem);
	line-height: 1;
	letter-spacing: -0.04em;
	color: var(--orange);
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}
.meter__value[data-idle="true"] { color: var(--ink-muted); }

.meter__note {
	font-size: var(--t-xs);
	color: var(--muted);
	margin-top: var(--s-3);
	text-align: center;
}

/* ---------- Wizard ---------- */

/* One page form. The client did not want a wizard, so the grouping has to do
   the work the steps used to: named sections with a rule between them, so a
   long form still reads as three short ones. */
.formsec + .formsec {
	margin-top: var(--s-5);
}
.formsec__title {
	font-size: 0.95rem;
	margin-bottom: var(--s-3);
}

.fieldset { border: 0; padding: 0; margin: 0 0 var(--s-4); min-width: 0; }
.fieldset--last { margin-bottom: 0; }
.field--last { margin-bottom: 0; }

.meter__note--left { text-align: left; }

.formsec--pay .js-submit { margin-top: var(--s-5); }

.paymenticons { display: flex; align-items: center; justify-content: center; flex-wrap: nowrap; gap: clamp(4px, 1.6vw, 14px); margin: var(--s-5) 0 0; }
.paymenticons__badge { flex: 1 1 0; min-width: 0; display: flex; justify-content: center; }
.paymenticons__badge img { display: block; height: auto; max-height: 32px; max-width: 100%; width: auto; opacity: .85; }
.paymenticons__badge--framed img { opacity: 1; }

/* ---------- Vehicle picker ---------- */

.vehgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr)); gap: var(--s-3); }

.vehopt { position: relative; }
.vehopt input { position: absolute; opacity: 0; pointer-events: none; }
.vehopt__box {
	display: block;
	background: var(--surface);
	border: 1.5px solid var(--line);
	border-radius: var(--radius);
	padding: var(--s-3);
	cursor: pointer;
	transition: border-color .15s var(--ease), background-color .15s var(--ease);
	height: 100%;
}
.vehopt__box:hover { border-color: #CFC9BB; }
.vehopt input:checked + .vehopt__box {
	border-color: var(--orange);
	background: var(--surface);
	box-shadow: 0 0 0 1px var(--orange) inset;
}
.vehopt input:focus-visible + .vehopt__box { outline: 3px solid var(--orange); outline-offset: 2px; }
.vehopt__box img { width: 100%; max-width: 108px; margin: 0 auto var(--s-2); }

/* Name and price share a row instead of stacking, so the surcharge reads as
   a badge next to the label rather than competing with it for the same
   line's weight. A divider then separates that header from the spec list,
   which carries a small icon per line instead of two lines of plain text
   with nothing to anchor a quick scan. */
.vehopt__head {
	display: flex; align-items: flex-start; justify-content: space-between;
	gap: 6px;
	padding-bottom: 8px;
	margin-bottom: 8px;
	border-bottom: 1px solid var(--line);
}
.vehopt__head b { font-family: var(--display); font-size: var(--t-sm); font-weight: 700; }
.vehopt__surcharge {
	flex-shrink: 0;
	font-family: var(--body);
	font-size: 11px;
	font-weight: 700;
	color: var(--orange);
	background: rgba(252,125,3,.12);
	border-radius: 999px;
	padding: 2px 8px;
	line-height: 1.5;
}
.vehopt__specs { display: grid; gap: 4px; }
.vehopt__spec {
	display: flex; align-items: flex-start; gap: 6px;
	font-size: var(--t-xs);
	line-height: 1.4;
	color: var(--muted);
}
/* Top aligned against the row, not centred against it: centring looks right
   for "4 seats" on one line, but tips the icon visibly high once "2 large
   and 2 small bags" wraps to two. A small nudge lines the icon up with the
   cap height of that first line instead of the row's literal top edge. */
.vehopt__spec svg { width: 14px; height: 14px; flex-shrink: 0; margin-top: 2px; color: var(--muted); }

/* ---------- Checkable list (extras, notes) ---------- */

/* One line answers. A boxed card with a hint under it is the right shape for
   choosing between things, and the wrong shape for a plain yes or no. */
.checklines { display: grid; gap: 0; }
.checkline {
	display: flex; align-items: center; gap: var(--s-3);
	min-height: 36px;
	padding: 1px 0;
	cursor: pointer;
	font-size: var(--t-sm);
	text-transform: capitalize;
}
.checkline input {
	accent-color: var(--orange);
	width: 18px; height: 18px;
	flex-shrink: 0;
	margin: 0;
}
.checkline span { min-width: 0; }

.checklist { display: grid; gap: var(--s-2); }
.checkitem {
	display: flex; gap: var(--s-3); align-items: flex-start;
	background: var(--surface);
	border: 1.5px solid var(--line);
	border-radius: var(--radius-sm);
	padding: 12px 14px;
	cursor: pointer;
	transition: border-color .15s var(--ease), background-color .15s var(--ease);
}
.checkitem:hover { border-color: #CFC9BB; }
/* Native checkboxes with accent-color render inconsistently across mobile
   browsers, some pad a large touch halo around the box itself, which threw
   the alignment off against the label text. Drawn by hand instead so the
   box is exactly 18px everywhere. */
.checkitem input {
	appearance: none; -webkit-appearance: none;
	margin: 3px 0 0; width: 18px; height: 18px; flex-shrink: 0;
	border: 1.5px solid var(--line); border-radius: 5px;
	background: var(--surface);
	position: relative;
	cursor: pointer;
}
.checkitem input:checked { background: var(--orange); border-color: var(--orange); }
.checkitem input:checked::after {
	content: ""; position: absolute; left: 5px; top: 1px;
	width: 5px; height: 9px;
	border: solid #fff; border-width: 0 2px 2px 0;
	transform: rotate(45deg);
}
.checkitem input:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
.checkitem:has(input:checked) { border-color: var(--orange); background: var(--surface); }
.checkitem b { display: block; font-size: var(--t-sm); font-weight: 600; }
.checkitem small { display: block; font-size: var(--t-xs); color: var(--muted); }
/* One line of text, not a stacked title and description: the checkbox
   centres with it instead of pinning to the top like it does for the
   two-line version. */
.checkitem--inline { align-items: center; }
.checkitem--inline input { margin: 0; }

/* Trip overview map, under the fare breakdown. Both ends and the route
   between them, with a floating card carrying the real distance and time,
   the same figures the fare itself is built from. */
.tripmap {
	position: relative;
	border-radius: var(--radius-sm);
	overflow: hidden;
	margin: var(--s-4) 0;
	border: 1.5px solid var(--line);
}
.tripmap[hidden] { display: none !important; }
.tripmap__map { width: 100%; height: 220px; background: var(--line-soft); }
.tripmap__card {
	position: absolute; left: 12px; bottom: 12px;
	background: var(--surface);
	border-radius: var(--radius-sm);
	box-shadow: 0 4px 14px rgba(11,11,13,.2);
	padding: 10px 14px;
	display: flex; align-items: baseline; gap: 8px;
}
.tripmap__card b { font-family: var(--display); font-size: var(--t-lg); }
.tripmap__card span { font-size: var(--t-xs); color: var(--muted); }

/* FAQ list on every page that is not the dedicated /faq/ page. One shared
   bordered group, not a stack of individually boxed cards: taken literally
   after "group of accordion, not separate accordion" kept coming back even
   once the single column and the centred heading were both already fixed.
   The dedicated /faq/ page's own .qa usage is untouched, since it sits
   inside .faqbody, not .faqgrid--single, and was never part of this ask. */
.faqgrid--single {
	grid-template-columns: 1fr;
	gap: 0;
	max-width: 760px;
	margin-inline: auto;
	border: 1px solid var(--line);
	border-radius: var(--radius);
	background: var(--surface);
	overflow: hidden;
}
.faqgrid--single .qa {
	border: 0;
	border-radius: 0;
	margin-bottom: 0;
	border-bottom: 1px solid var(--line);
}
.faqgrid--single .qa:last-child { border-bottom: 0; }

/* Reviews marquee. A continuous CSS animation, not JS: cheaper, and it
   cannot get stuck if a script fails to load. The track is exactly two
   copies of the review list side by side; sliding it left by precisely one
   copy's width (50%, since there are two equal copies) and jumping back to
   0% at the same instant is what makes the loop invisible. */
.reviewmarquee { overflow: hidden; margin-inline: calc(var(--s-5) * -1); }
.reviewmarquee__track {
	display: flex;
	gap: var(--s-4);
	width: max-content;
	padding-inline: var(--s-5);
	animation: mt13-marquee 34s linear infinite;
}
.reviewmarquee:hover .reviewmarquee__track,
.reviewmarquee__track:has(:focus-visible) {
	animation-play-state: paused;
}
.reviewmarquee .reviewcard { flex: 0 0 300px; }
@keyframes mt13-marquee {
	to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
	.reviewmarquee__track { animation: none; }
	.reviewmarquee { overflow-x: auto; }
}

/* Review score line: G mark, the number, five stars, then the count. */
.reviewscore {
	display: flex; align-items: center; justify-content: center; gap: 8px;
	margin-top: var(--s-3);
	font-size: var(--t-base);
}
.reviewscore b { font-size: var(--t-lg); font-family: var(--display); }
.reviewscore__stars { display: inline-flex; gap: 2px; color: #F5A623; }
.reviewscore__stars svg { width: 16px; height: 16px; fill: currentColor; stroke: none; }

.reviewcard { text-decoration: none; color: var(--text); }
.reviewcard__stars { display: flex; gap: 2px; color: #F5A623; margin-bottom: var(--s-3); }
.reviewcard__stars svg { width: 15px; height: 15px; fill: currentColor; stroke: none; }
.reviewcard p { color: var(--text); }
.reviewcard b { display: flex; align-items: center; gap: 6px; color: var(--muted); font-weight: 600; }

/* ---------- Cards and grids ---------- */

/* Wide content scrolls inside its own box, never the page. */
.tbl-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }

.grid { display: grid; gap: var(--s-5); }
/* Grid and flex children default to min-width:auto and will not shrink below
   their content, which is how one long word or a wide table drags the whole
   page sideways. */
.grid > *, .booklayout > *, .contactlayout > *, .hero__grid > * { min-width: 0; }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }

.card {
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	padding: var(--s-5);
	transition: border-color .18s var(--ease), transform .18s var(--ease), box-shadow .18s var(--ease);
}
.card:hover { border-color: #D6D0C2; transform: translateY(-2px); box-shadow: var(--shadow-sm); }
.card h3 { margin-bottom: var(--s-2); }
.card__media {
	aspect-ratio: 16 / 9;
	width: 100%;
	object-fit: cover;
	border-radius: var(--radius-sm);
	background: var(--line-soft);
	margin-bottom: var(--s-4);
}
/* Vehicle photos, not blog thumbnails: cover crops whatever does not fit the
   box, and on a car that is the front bumper and roofline, exactly what
   matters for "which car is this". The source photos run 1.95:1 to 2.36:1,
   wider than the 16:9 box, so this widens it and shows the full car with a
   little padding either side rather than cropping it. */
.card__media--fit {
	aspect-ratio: 2 / 1;
	object-fit: contain;
	padding: var(--s-3);
	/* The base .card__media rule's grey letterbox background is right for a
	   cropped blog thumbnail filling its box edge to edge; here contain
	   leaves visible space around the car, and that space needs to be white,
	   not grey, to actually read as "white background". */
	background: var(--surface);
}

/* Homepage fleet cards. A hair more lift than the generic .card hover, since
   these are the closest thing the homepage has to product cards. */
.card--veh:hover .card__media--fit { background: var(--paper); }
.card--veh__blurb { color: var(--muted); margin-bottom: var(--s-3); min-height: 2.6em; }
.card p { font-size: var(--t-sm); color: var(--muted); margin: 0; }

/* Four across on desktop (there are always exactly four vehicles), a
   horizontal scroll carousel below tablet width instead of a cramped single
   column stack. */
@media (max-width: 768px) {
	.fleetgrid {
		display: flex;
		grid-template-columns: none;
		overflow-x: auto;
		scroll-snap-type: x proximity;
		-webkit-overflow-scrolling: touch;
		padding-bottom: 6px;
		margin: 0 -4px;
	}
	.fleetgrid .card--veh {
		flex: 0 0 clamp(220px, 70vw, 280px);
		scroll-snap-align: start;
	}
}

.card--link { text-decoration: none; display: block; }

.cardicon {
	width: 44px; height: 44px; border-radius: 11px;
	background: rgba(252,125,3,.14);
	color: var(--orange);
	display: grid; place-items: center;
	margin-bottom: var(--s-4);
}

/* ---------- Footer ---------- */

.site-footer { background: var(--ink); color: var(--ink-muted); padding-block: var(--s-8) var(--s-5); }
.site-footer h4 {
	font-family: var(--display); font-size: var(--t-sm); font-weight: 700;
	color: #fff; letter-spacing: .04em; margin: 0 0 var(--s-4);
}
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
/* Scoped past the header's own .brand img rule: bigger here only, the header
   logo is untouched. */
.site-footer .brand img { height: 56px; }
/* :not(.btn) matters. Without it this rule repaints the phone button's label
   grey on orange, which is unreadable and is exactly how the FAQ call to
   action ended up white on white. */
.site-footer a:not(.btn) { color: var(--ink-muted); text-decoration: none; font-size: var(--t-sm); }
.site-footer a:not(.btn):hover { color: #fff; }
.footer__grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: var(--s-6); }
.footer__bottom {
	margin-top: var(--s-7); padding-top: var(--s-5);
	border-top: 1px solid var(--ink-line);
	display: flex; flex-wrap: wrap; gap: 6px var(--s-3); justify-content: center;
	text-align: center;
	font-size: var(--t-xs);
}

/* ---------- Sticky mobile action bar ----------
   On a phone the two things that matter are call and book. They stay put. */

.actionbar {
	display: none;
	position: fixed; bottom: 0; left: 0; right: 0; z-index: 90;
	align-items: stretch;
	padding-bottom: env(safe-area-inset-bottom);
	box-shadow: 0 -4px 20px rgba(11,11,13,.1);
	overflow: visible;
}
/* Two flush halves, one bar. No gap, no radius between them, only the outer
   corners rounded, so the two colours read as one connected control rather
   than two buttons sitting side by side. */
.actionbar__half {
	flex: 1;
	display: flex; align-items: center; justify-content: center;
	min-height: 56px;
	font-family: var(--display); font-weight: 700; font-size: .92rem;
	color: #fff; text-decoration: none;
	white-space: nowrap;
	text-transform: uppercase;
}
.actionbar__half--book { background: var(--orange); padding-right: 34px; }
.actionbar__half--call { background: var(--ink); padding-left: 34px; }
/* The phone itself, raised on the seam. This is the one action a passenger
   in a hurry reaches for first, so it gets the visual weight, not just a
   label like the other two. */
.actionbar__call {
	position: absolute; left: 50%; top: -18px;
	transform: translateX(-50%);
	width: 52px; height: 52px; border-radius: 50%;
	background: #fff; color: var(--orange);
	display: grid; place-items: center;
	box-shadow: 0 4px 14px rgba(11,11,13,.25);
	border: 3px solid var(--paper);
}
.actionbar__call svg { width: 22px; height: 22px; }

/* Three segment version. Kept the two-half-plus-circle rules above rather
   than delete them, since this exact component has flipped back and forth
   more than once already and re-adding them from scratch would be pure
   churn if it changes again. */
.actionbar--three { align-items: stretch; }
.actionbar__third {
	flex: 1;
	min-width: 0;
	display: flex; align-items: center; justify-content: center; gap: 5px;
	min-height: 56px;
	padding-inline: 3px;
	font-family: var(--display); font-weight: 700;
	/* A fixed .82rem sat at an exact three-way fit in testing, with no
	   margin for a real device's font metrics to differ even slightly.
	   Fluid sizing keeps a floor so it can give up a little width instead
	   of forcing the row a hair past 100%. */
	font-size: clamp(.72rem, 3.1vw, .82rem);
	color: #fff; text-decoration: none;
	white-space: nowrap;
	text-transform: uppercase;
}
.actionbar__third svg { width: 17px; height: 17px; flex-shrink: 0; }
.actionbar__third--book     { background: var(--orange); }
.actionbar__third--call     { background: var(--ink); }
.actionbar__third--whatsapp { background: #25D366; }

/* Two flat halves with the Google mark as a real circle sitting inline
   between them, at the bar's own height, not raised above it like the
   earlier version. A normal flex item, not position:absolute. */
.actionbar--pair {
	display: flex;
	align-items: stretch;
	background: var(--ink);
}
/* .actionbar__half is reused by the older two-half-plus-raised-circle rules
   above (kept, unused, in case this component flips again), which is exactly
   why the book/call halves here use their own unique classes rather than
   --book/--call modifiers: those modifier names already exist up there with
   a padding-left/right meant to clear space for a circle that overlapped
   from the edge in that version. Reusing them silently carried that padding
   into this version too, since a later rule only overrides properties it
   explicitly redeclares, not ones it never mentions. That is exactly the bug
   that shifted "Call" off centre here before this was split out. */
.actionbar__half {
	flex: 1;
	display: flex; align-items: center; justify-content: center;
	min-height: 56px;
	font-family: var(--display); font-weight: 700; font-size: .92rem;
	color: #fff; text-decoration: none;
	gap: 6px;
	white-space: nowrap;
}
.actionbar__pairbook { background: var(--orange); }
.actionbar__paircall { background: var(--ink); }
.actionbar__half svg { width: 17px; height: 17px; flex-shrink: 0; }
.actionbar__g {
	flex: 0 0 auto;
	width: 44px; height: 44px; margin: auto 8px;
	border-radius: 50%;
	background: #fff;
	display: grid; place-items: center;
	box-shadow: 0 1px 4px rgba(11,11,13,.25);
}
.actionbar__g svg { width: 22px; height: 22px; }
/* WhatsApp's own glyph is a solid white mark, meant to sit on their brand
   green, not the white-circle treatment the Google G needed to show its own
   colours correctly. */
.actionbar__g--whatsapp { background: #25D366; color: #fff; }

/* ---------- Responsive ---------- */

@media (max-width: 1080px) {
	.nav__list { gap: var(--s-4); }
	.nav__list a { font-size: 13.5px; }
	.hero__grid { grid-template-columns: 1fr minmax(360px, 420px); }
}

@media (max-width: 1100px) {
	.nav { display: none; }
	.navtoggle { display: inline-flex; }
	.callnow__txt { display: none; }
	/* The nav carries the margin-left:auto that pushes this group right, so
	   with the nav hidden the actions have to claim that space themselves. */
	.header__actions { margin-left: auto; }

	/* On a phone the booking card is the job, so it comes early. It does not
	   come first though: landing on a bare pair of address fields, with no
	   headline above them, gives no clue what the site even is. The heading
	   leads, the card follows straight after it, and the supporting copy sits
	   underneath. display:contents lifts the copy block's children up into the
	   grid so they can be ordered around the card without duplicating markup. */
	.hero__grid { grid-template-columns: 1fr; gap: 0; }
	.hero__copy { display: contents; }
	.hero__copy > * { min-width: 0; }
	.hero__copy > .eyebrow { order: 1; }
	.hero__copy > h1 { order: 2; margin: 10px 0 22px; }
	.hero__form { order: 3; margin-bottom: 26px; }
	.hero__copy > .hero__lede { order: 4; margin-bottom: 20px; }
	.hero__copy > .trustrow { order: 5; }

	.footer__grid { grid-template-columns: 1fr 1fr; gap: var(--s-5); }
}

@media (max-width: 660px) {
	/* A percentage flex-basis here is what caused the actual bug: the track
	   is width:max-content (it has to be, for the marquee animation's own
	   math to work), so a child asking for a percentage of that has nothing
	   real to resolve against and blew out to several thousand pixels wide,
	   the card rendering as unstyled overflowing text with no visible border.
	   A fixed width has a real number to be a percentage, or rather, be
	   fixed, of. */
	.reviewmarquee .reviewcard { flex-basis: 260px; }
	/* The sticky action bar carries booking on a phone, so the header button
	   comes out rather than being squeezed. */
	.header__actions .btn--primary { display: none; }
	.site-header__bar { gap: var(--s-3); }
}

/* Touch targets. Keyed to the pointer rather than the width, because a tablet
   is a wide screen you still operate with a finger. Hit areas grow with
   padding, so nothing changes visually, the target just stops being fiddly.
   The width branch carries phones and tablets, which is also where the mobile
   nav takes over, and the pointer branch picks up touch laptops that are wider
   than that. Left alone on a mouse driven desktop, where a 16px link is
   perfectly clickable and padding every footer link out to 44px would only
   double the footer's height for nothing. */
@media (max-width: 1100px), (pointer: coarse) {
	.locate { width: 44px; height: 44px; }
	/* The icon grew, so the text has to clear it by more than it did before. */
	.field__with-btn input { padding-right: 58px; }
	.callnow__icon { width: 44px; height: 44px; }
	.brand { padding-block: 6px; min-height: 44px; display: inline-flex; align-items: center; }
	.nav__list a { display: flex; align-items: center; min-height: 44px; }
	.site-footer ul { gap: 0; }
	.site-footer ul a {
		display: flex; align-items: center;
		min-height: 38px; padding-block: 6px;
	}
}

@media (max-width: 620px) {
	/* Two short lines stacked and left aligned reads clean; space-between
	   with only two items and not much width to work with was wrapping them
	   unevenly, one hugging the right edge on its own line. */
	.footer__bottom { flex-direction: column; align-items: center; gap: var(--s-2); }

	.wrap { padding-inline: var(--s-4); }
	/* Matches .wrap's narrower padding at this width, or the review row's
	   edges stop lining up with the rest of the page's content. */
	.reviewmarquee { margin-inline: calc(var(--s-4) * -1); }
	.reviewmarquee__track { padding-inline: var(--s-4); }
	.bookcard__body { padding: var(--s-4); }
	.field-row { grid-template-columns: 1fr; }
	.field-row--split { grid-template-columns: 1fr 1fr; gap: var(--s-2); }
	.meter { flex-direction: column; align-items: flex-start; gap: var(--s-2); }
	.footer__grid { grid-template-columns: 1fr; }
	.actionbar { display: flex; }
	/* On the footer itself, not body: body's own background is the light
	   paper tone, so padding reserved there for the fixed bar showed up as a
	   mismatched pale gap between the black footer and the bar. The footer's
	   own black background fills the same reserved space correctly instead.
	   Also right sized now: 56px bar height, not the 92px this held over from
	   the earlier version where the phone circle was raised 18px above the
	   bar rather than sitting inline within it. */
	.site-footer { padding-bottom: calc(var(--s-5) + 56px); }
	.trustrow { gap: var(--s-3) var(--s-5); }
}

/* ---------- Nav drawer (mobile) ---------- */

.drawer {
	position: fixed; inset: 0; z-index: 200;
	background: var(--ink);
	padding: var(--s-5);
	overflow-y: auto;
	display: none;
}
.drawer.is-open { display: block; }
.drawer__top { display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--s-6); }
.drawer ul { list-style: none; margin: 0 0 var(--s-6); padding: 0; display: grid; gap: 2px; }
.drawer__nav ul { list-style: none; margin: 0; padding: 0; }
.drawer__group summary {
	display: flex; align-items: center; justify-content: space-between;
	min-height: 48px; padding: 13px 0;
	border-bottom: 1px solid var(--ink-line);
	color: #fff; cursor: pointer; list-style: none;
	font-family: var(--display); font-weight: 600; font-size: var(--t-lg);
}
.drawer__group summary::-webkit-details-marker { display: none; }
.drawer__group summary svg { width: 20px; height: 20px; transition: transform .18s var(--ease); }
.drawer__group[open] summary svg { transform: rotate(180deg); }
/* The children sit indented under their heading so the grouping reads at a
   glance, rather than looking like eleven equal items. */
.drawer__group > ul { padding-left: var(--s-4); }
.drawer__group > ul a {
	font-size: var(--t-base);
	font-weight: 500;
	opacity: .82;
}

.drawer ul a {
	display: flex; align-items: center; min-height: 48px;
	color: #fff; text-decoration: none;
	font-family: var(--display); font-weight: 600; font-size: var(--t-lg);
	padding: 13px 0; border-bottom: 1px solid var(--ink-line);
}

/* ---------- Suburb and route page components ---------- */

/* A page hero is shorter than the home hero: the headline has already been
   earned by the search result that brought them here. */
.hero--page { padding-block: clamp(28px, 4vw, 52px) clamp(40px, 6vw, 72px); }
.hero--page h1 { font-size: var(--t-3xl); }

/* A service page's own photo, sitting between the hero and the first content
   section. Kept out of hero__grid entirely rather than added as a third
   column: that grid already reorders on mobile via display:contents, and a
   photo dropped into it would have to be threaded through that same order
   logic. A separate block underneath has no such entanglement. */
.svcphoto-wrap { padding-block: 0 clamp(28px, 4vw, 48px); }
.svcphoto { display: block; width: 100%; height: clamp(200px, 30vw, 400px); object-fit: cover; border-radius: var(--radius-lg); }

/* Fare tables. Tabular figures so the dollar columns line up down the page. */
.fares { width: 100%; border-collapse: collapse; font-size: var(--t-sm); }
.fares th, .fares td { padding: 13px 14px; text-align: left; }
.fares thead th {
	font-family: var(--display);
	font-size: var(--t-xs);
	text-transform: uppercase;
	letter-spacing: .1em;
	color: var(--muted);
	border-bottom: 2px solid var(--line);
	white-space: nowrap;
}
.fares tbody th { font-weight: 700; }
.fares a { display: inline-block; padding: 6px 0; min-height: 32px; }
@media (max-width: 768px) {
	.fares a { padding: 11px 0; min-height: 44px; }
}
.fares tbody tr { border-bottom: 1px solid var(--line-soft); }
.fares tbody tr:last-child { border-bottom: 0; }
.fares tbody tr:hover { background: var(--paper); }

/* Neighbour links. Real distances, so the row is information rather than a
   wall of keyword links. */
.svccarousel {
	display: flex;
	gap: var(--s-5);
	overflow-x: auto;
	scroll-snap-type: x proximity;
	-webkit-overflow-scrolling: touch;
	padding-bottom: 6px;
	margin: 0 -4px;
}
.svccarousel__card {
	flex: 0 0 clamp(240px, 27vw, 300px);
	scroll-snap-align: start;
	display: flex;
	flex-direction: column;
	gap: 12px;
	text-decoration: none;
	color: var(--text);
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	padding: var(--s-4);
	transition: border-color .18s var(--ease), transform .18s var(--ease), box-shadow .18s var(--ease);
}
.svccarousel__card:hover { border-color: #D6D0C2; transform: translateY(-2px); box-shadow: var(--shadow-sm); }
.svccarousel__media {
	width: 100%;
	height: clamp(150px, 14vw, 190px);
	object-fit: cover;
	border-radius: var(--radius-sm);
	display: block;
}
.svccarousel__icon {
	width: 100%;
	height: clamp(150px, 14vw, 190px);
	border-radius: var(--radius-sm);
	background: var(--line-soft);
	display: grid;
	place-items: center;
	color: var(--orange);
}
.svccarousel__title { font-weight: 700; font-size: var(--t-base); line-height: 1.3; }
.svccarousel__card:hover .svccarousel__title { color: var(--orange); }
.svccarousel__copy { font-size: var(--t-sm); color: var(--muted); line-height: 1.45; margin-top: -4px; }

.pillrow { display: flex; flex-wrap: wrap; gap: 10px; }
.pill {
	display: inline-flex;
	align-items: baseline;
	gap: 8px;
	padding: 12px 18px;
	min-height: 44px;
	border: 1.5px solid var(--line);
	border-radius: 999px;
	text-decoration: none;
	font-size: var(--t-sm);
	font-weight: 600;
	transition: border-color .15s var(--ease), background-color .15s var(--ease);
}
.pill span { font-weight: 400; color: var(--muted); font-size: var(--t-xs); }
.pill:hover { border-color: var(--orange); background: rgba(252,125,3,.06); }

@media (max-width: 620px) {
	.fares th, .fares td { padding: 11px 10px; }
}

/* ---------- Service areas hub ---------- */

.arealist {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
	gap: 2px;
	border: 1px solid var(--line);
	border-radius: var(--radius);
	overflow: hidden;
	background: var(--line);
}
.areaitem {
	display: block;
	background: var(--surface);
	padding: 14px 18px;
	min-height: 56px;
	text-decoration: none;
	transition: background-color .15s var(--ease);
}
.areaitem:hover { background: rgba(252,125,3,.07); }
.areaitem b { display: block; font-size: var(--t-sm); font-weight: 700; }
.areaitem span { display: block; font-size: var(--t-xs); color: var(--muted); margin-top: 2px; }

/* ---------- Booking page ---------- */

.booklayout { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: var(--s-6); align-items: start; }

.steps { list-style: none; margin: 0; padding: 0; counter-reset: step; display: grid; gap: 14px; }
.steps li { counter-increment: step; padding-left: 38px; position: relative; }
.steps li::before {
	content: counter(step);
	position: absolute; left: 0; top: 0;
	width: 26px; height: 26px; border-radius: 50%;
	background: var(--orange); color: var(--ink);
	font-family: var(--display); font-weight: 800; font-size: 13px;
	display: grid; place-items: center;
}
.steps b { display: block; font-size: var(--t-sm); }
.steps span { display: block; font-size: var(--t-xs); color: var(--muted); }

.ticks { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.ticks li { padding-left: 26px; position: relative; font-size: var(--t-sm); color: var(--muted); }
.ticks li::before {
	content: "";
	position: absolute; left: 0; top: 7px;
	width: 14px; height: 8px;
	border-left: 2.5px solid var(--vacant);
	border-bottom: 2.5px solid var(--vacant);
	transform: rotate(-45deg);
}

@media (max-width: 900px) {
	.booklayout { grid-template-columns: 1fr; }
	/* The reassurance panel belongs under the form on a phone, not above it. */
	.booklayout__side { order: 2; }
	.booklayout__form { order: 1; }
}

/* ---------- Fares page ---------- */

.rate {
	font-family: var(--display);
	font-weight: 800;
	font-size: 1.6rem;
	letter-spacing: -0.03em;
	color: var(--orange);
	font-variant-numeric: tabular-nums;
	margin-bottom: 6px;
}

/* The estimator's working, shown above the total. */
.farebreak {
	margin-top: var(--s-4);
	border-top: 1px solid var(--line);
	padding-top: var(--s-3);
}
/* Review step summary. The label must not shrink: flex items default to
   min-width:auto, so a long value squeezes the label until it wraps one
   character per line, which is how "Return" rendered as Re / tur / n. */
.summary { display: grid; gap: 8px; margin: 0; font-size: var(--t-sm); }
.summary__row {
	display: flex; gap: var(--s-4); justify-content: space-between;
	border-bottom: 1px solid var(--line-soft);
	padding-bottom: 6px;
}
.summary__row dt { color: var(--muted); flex-shrink: 0; white-space: nowrap; }
.summary__row dd {
	margin: 0; font-weight: 600; text-align: right;
	min-width: 0; overflow-wrap: break-word;
}

.farebreak__row {
	display: flex;
	justify-content: space-between;
	gap: var(--s-4);
	padding: 7px 0;
	font-size: var(--t-sm);
	color: var(--muted);
	border-bottom: 1px solid var(--line-soft);
}
/* Leg headings in a return quote. Without them the breakdown reads as one long
   list of charges and the total looks wrong. */
.farebreak__row--head {
	font-weight: 700;
	color: var(--text);
	border-top: 1px solid var(--line);
	margin-top: 4px;
	padding-top: 8px;
}

.farebreak__row:last-child { border-bottom: 0; }
.farebreak__row b { color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---------- Fleet specs ---------- */

.spec { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: var(--t-xs); color: var(--muted); }
.spec b { color: var(--text); font-weight: 700; }
.spec span { display: flex; align-items: center; gap: 6px; }
.spec svg { width: 14px; height: 14px; flex-shrink: 0; color: var(--muted); }

/* ---------- FAQ page ---------- */

.faqlayout { display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: var(--s-7); align-items: start; }
.faqlayout > * { min-width: 0; }

.faqnav { position: sticky; top: 100px; }
.faqnav b { display: block; font-family: var(--display); font-size: var(--t-xs); letter-spacing: .12em; text-transform: uppercase; color: var(--muted); margin-bottom: var(--s-3); }
.faqnav ul { list-style: none; margin: 0 0 var(--s-5); padding: 0; display: grid; gap: 2px; }
.faqnav ul a { display: flex; align-items: center; min-height: 44px; text-decoration: none; font-size: var(--t-sm); padding: 9px 12px; border-radius: 8px; color: var(--muted); }
.faqnav ul a:hover { background: var(--surface); color: var(--text); }

.faqgroup { margin-bottom: var(--s-7); }
.faqgroup:last-child { margin-bottom: 0; }
.faqgroup h2 { margin-bottom: var(--s-4); }

.qa {
	border: 1px solid var(--line);
	border-radius: var(--radius);
	background: var(--surface);
	margin-bottom: 10px;
	overflow: hidden;
}
.qa summary {
	cursor: pointer;
	padding: 15px 18px;
	font-weight: 600;
	font-size: var(--t-base);
	list-style: none;
	display: flex;
	justify-content: space-between;
	gap: var(--s-4);
	align-items: flex-start;
}
.qa summary::-webkit-details-marker { display: none; }
.qa summary::after {
	content: "";
	flex-shrink: 0;
	width: 9px; height: 9px;
	margin-top: 6px;
	border-right: 2px solid var(--muted);
	border-bottom: 2px solid var(--muted);
	transform: rotate(45deg);
	transition: transform .2s var(--ease);
}
.qa[open] summary::after { transform: rotate(-135deg); }
.qa p { padding: 0 18px 16px; color: var(--muted); font-size: var(--t-sm); margin: 0; }

/* ---------- Contact ---------- */

.contactlayout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: var(--s-6); align-items: start; }

.contactcard {
	display: flex;
	align-items: center;
	gap: var(--s-4);
	padding: 18px 20px;
	border: 1.5px solid var(--line);
	border-radius: var(--radius);
	background: var(--surface);
	text-decoration: none;
	margin-bottom: 12px;
	transition: border-color .15s var(--ease), transform .15s var(--ease);
}
.contactcard:hover { border-color: var(--orange); transform: translateY(-1px); }
.contactcard__icon {
	width: 46px; height: 46px; border-radius: 12px; flex-shrink: 0;
	background: rgba(252,125,3,.12); color: var(--orange);
	display: grid; place-items: center;
}
.contactcard small { display: block; font-size: var(--t-xs); color: var(--muted); }
.contactcard b { font-family: var(--display); font-size: var(--t-lg); letter-spacing: -0.02em; word-break: break-word; }
.contactcard--primary { background: var(--ink); border-color: var(--ink); }
.contactcard--primary small { color: var(--ink-muted); }
.contactcard__icon--whatsapp { background: rgba(37,211,102,.14); color: #25D366; }
.contactcard--primary b { color: #fff; }
.contactcard--primary .contactcard__icon { background: rgba(252,125,3,.2); color: var(--orange); }

/* Honeypot. Off screen rather than display:none, which some bots skip. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

@media (max-width: 900px) {
	.faqlayout { grid-template-columns: minmax(0, 1fr); gap: var(--s-5); }
	.faqnav { position: static; min-width: 0; }
	/* The chip row scrolls inside itself. Without the explicit min-width:0 the
	   track grows to fit every chip and takes the page with it. */
	.faqnav ul {
		display: flex;
		flex-wrap: nowrap;
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
		gap: 6px;
		padding-bottom: 6px;
		min-width: 0;
		scrollbar-width: thin;
	}
	.faqnav li { flex: 0 0 auto; }
	.faqnav ul a { white-space: nowrap; border: 1px solid var(--line); background: var(--surface); }
	.contactlayout { grid-template-columns: 1fr; }
}

/* ---------- Blog ---------- */

.postcard time { display: block; font-size: var(--t-xs); color: var(--muted); margin-bottom: 6px; }
.postcard h2 { font-size: 1.05rem; line-height: 1.3; margin-bottom: 8px; letter-spacing: -0.01em; }

.pagination { display: flex; justify-content: center; gap: 6px; margin-top: var(--s-6); flex-wrap: wrap; }
.pagination .page-numbers {
	display: inline-flex; align-items: center; justify-content: center;
	min-width: 42px; height: 42px; padding: 0 14px;
	border: 1px solid var(--line); border-radius: var(--radius-sm);
	background: var(--surface); text-decoration: none; font-size: var(--t-sm); font-weight: 600;
}
.pagination .page-numbers:hover { border-color: var(--text); }
.pagination .page-numbers.current { background: var(--orange); border-color: var(--orange); color: var(--ink); }

/* ---------- Article ---------- */

.article { max-width: 760px; }
.backlink { display: inline-block; font-size: var(--t-sm); color: var(--muted); text-decoration: none; margin-bottom: var(--s-4); padding: 10px 0; min-height: 44px; }
.backlink:hover { color: var(--text); }
.articlemeta { font-size: var(--t-sm); color: var(--muted); margin-bottom: var(--s-6); }

.entry { font-size: 1.05rem; line-height: 1.8; }
.entry h2 { font-size: var(--t-2xl); margin-top: var(--s-7); }
.entry h3 { font-size: var(--t-xl); margin-top: var(--s-6); }
.entry p { margin-bottom: var(--s-4); }
.entry ul, .entry ol { margin: 0 0 var(--s-4); padding-left: 1.3em; }
.entry li { margin-bottom: 8px; }
.entry img { border-radius: var(--radius); margin: var(--s-5) 0; }
.entry a:not(.btn) { color: var(--orange); text-underline-offset: 3px; }
/* Inline links inside a sentence are deliberately left at line height. WCAG
   2.5.8 exempts them, and an enlarged overlay would sit on top of the lines
   above and below and steal their taps, which is worse than the thing it
   claims to fix. */
.entry blockquote {
	margin: var(--s-5) 0; padding: var(--s-4) var(--s-5);
	border-left: 3px solid var(--orange); background: var(--surface);
	border-radius: 0 var(--radius) var(--radius) 0;
}
.entry table { width: 100%; border-collapse: collapse; font-size: var(--t-sm); }
.entry th, .entry td { padding: 10px 12px; border-bottom: 1px solid var(--line); text-align: left; }

.articlecta {
	margin-top: var(--s-7);
	padding: var(--s-5);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	background: var(--surface);
}

/* ---------- Layout utilities ----------
   These exist so templates stop reaching for inline styles. An inline style
   cannot be overridden by a media query, so a hardcoded 48px gap stays 48px on
   a 360px phone. Anything spacing related belongs here instead. */

.grid--roomy { gap: clamp(28px, 5vw, 48px); }
.grid--middle { align-items: center; }
.grid--top { align-items: start; }

.narrow { max-width: 820px; }
.narrower { max-width: 640px; }

/* Button rows. Wrap, and go full width on the smallest screens so two buttons
   never end up as awkward half-width stubs. */
.btnrow { display: flex; gap: 12px; flex-wrap: wrap; }
.btnrow--center { justify-content: center; }
/* Both buttons the same width, the wider of the two decides it. Scoped, not
   applied to .btnrow generally, since most CTA pairs on the site are fine
   sized to their own content and forcing that everywhere would make short
   labels look padded and odd. */
/* min-width:0 matters: flex items default to min-width:auto, which refuses
   to shrink below content size regardless of flex-shrink, and that is why
   these two wrapped onto separate lines on a narrow phone instead of sharing
   the row like flex:1 1 0 alone should have guaranteed. */
.btnrow--even { flex-wrap: nowrap; }
.btnrow--even .btn {
	flex: 1 1 0;
	min-width: 0;
	white-space: nowrap;
	/* Same width does not mean same content length: "Book a taxi" and a full
	   phone number are different widths of text, so the phone button's own
	   font size flexes down fluidly to whatever fits its equal share of the
	   row, rather than either wrapping onto two lines or overflowing it. */
	font-size: clamp(.85rem, 3.6vw, 1.05rem);
}
/* The icon has no flex-shrink protection anywhere else in .btn, since this
   is the first place a button with an icon sits in a width this tight. Left
   unset it shrank to 0x0 rather than the text, which is backwards: the
   number is what needs to stay legible. */
.btnrow--even .btn svg { flex-shrink: 0; width: 18px; height: 18px; }
@media (min-width: 420px) {
	.btnrow--even .btn { flex: 0 1 220px; }
}

@media (max-width: 420px) {
	.btnrow { flex-direction: column; align-items: stretch; }
	.btnrow .btn { width: 100%; }
	/* .btnrow--even opts back out: its whole point is staying side by side
	   at equal width, which the stacked default above would undo. */
	.btnrow--even { flex-direction: row; }
	.btnrow--even .btn { width: auto; }
}

.meter--sm .meter__value { font-size: clamp(1.35rem, 1.1rem + 1vw, 1.6rem); }

/* Long unbroken strings (an address, an email) must never widen the page. */
.card, .qa, .entry, .contactcard, .meter__label { overflow-wrap: anywhere; }

/* ---------- Search ---------- */

.searchwrap { margin-top: var(--s-5); max-width: 520px; }

.searchform { display: flex; gap: 8px; }
.searchform input[type="search"] {
	flex: 1;
	min-width: 0;
	font-family: var(--body);
	font-size: var(--t-base);
	padding: 13px 14px;
	border: 1.5px solid var(--ink-line);
	border-radius: var(--radius-sm);
	background: var(--ink-soft);
	color: #fff;
}
.searchform input[type="search"]::placeholder { color: var(--ink-muted); }
.searchform input[type="search"]:focus {
	outline: none;
	border-color: var(--orange);
	box-shadow: 0 0 0 3px rgba(252,125,3,.25);
}
.searchform .btn { flex: 0 0 auto; }

@media (max-width: 480px) {
	.searchform { flex-direction: column; }
	.searchform .btn { width: 100%; }
}
