/**
 * Shiprocket Shipping Calculator — unified single-page design system.
 *
 * ONE cohesive language: every component (tabs, inputs, input groups, buttons,
 * segmented control, badges, cards, result rows) is built from the same design
 * tokens below — spacing, type scale, radii, colours, shadows, motion. No
 * component styles itself ad-hoc.
 *
 * Ancestor-independent: the plugin base `.calcComponentStyle input|button`
 * (0,1,1) is beaten with repeated-class selectors (.srInput.srInput → 0,2,0) so
 * the system looks identical inside or outside .calcComponentStyle (standalone
 * Bulk/Quick). Shared by the Vue calculator and the jQuery Bulk/Quick forms.
 *
 * @package Sr_shc
 */

/* ── Design tokens ──────────────────────────────────────────────────────── */
.srCalc, .srCard, .srInlineResult {
	/* colour — muted/faint/ok/err retuned in v0.4.2 to pass WCAG AA (4.5:1) at
	   their actual usage size against their actual background; see the audit.
	   --muted 8b90a8→6b7086 (3.16:1→4.90:1 on white), --faint 2.94:1 on white
	   (placeholder-only, exempt from AA but improved for readability), --err
	   e5484d→d1373c (3.91:1→4.86:1 on white), --ok 16a06a→0c7a4f (3.02:1→4.84:1
	   on --ok-bg, where the CHEAPEST chip text actually sits). */
	--brand: #6f57e9; --brand-2: #5b45d6; --brand-soft: #f5f3fe; --brand-line: #e3dffa;
	--ink: #0b0757; --ink-2: #3a3d5c; --muted: #6b7086; --faint: #9096ad;
	--line: #ecebf5; --field-line: #e9e7f4; --tint: #f4f3fb; --surface: #faf9ff;
	--ok: #0c7a4f; --ok-bg: #e7f7ef; --info: #4457d6; --info-bg: #eef0ff; --err: #d1373c;
	/* spacing (0.5.10) — the ONLY source for new spacing values. Existing
	   literal values are grandfathered (see DESIGN-GUIDELINES.md §3): keep
	   them until their rule is next rewritten, then round to a token. */
	--space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px;
	--space-5: 20px; --space-6: 24px; --space-7: 32px; --space-8: 40px;
	/* radius */
	--r-sm: 8px; --r: 12px; --r-lg: 16px; --r-card: 20px;
	/* type scale */
	--fs-xs: 11.5px; --fs-sm: 12.5px; --fs-cap: 13.5px; --fs: 14.5px; --fs-in: 15px; --fs-h: 18px; --fs-title: 22px;
	/* shadow */
	--sh-card: 0 12px 32px rgba(11, 7, 87, 0.06); --sh-btn: 0 8px 20px rgba(111, 87, 233, 0.28);
	--sh-row: 0 4px 16px rgba(11, 7, 87, 0.06);
	/* motion */
	--ease: cubic-bezier(0.4, 0, 0.2, 1); --dur: 0.22s;
	box-sizing: border-box;
}
.srCalc *, .srCalc *::before, .srCalc *::after,
.srCard *, .srCard *::before, .srCard *::after,
.srInlineResult *, .srInlineResult *::before, .srInlineResult *::after { box-sizing: border-box; }

/* ── Card ───────────────────────────────────────────────────────────────── */
/* max-width 100%: the card fills whatever container the page/theme gives it
   (was capped at 1080px for the 0.5.0 split; per request the page column now
   decides the width). Narrow variants still opt out of the split below. */
.srCalc, .srCard, .srInlineResult {
	width: 100%; max-width: 100%; margin: 0 auto;
	background: #ffffff; border: 1px solid var(--line); border-radius: var(--r-card);
	box-shadow: var(--sh-card);
}
/* !important: legacy `.calcComponentStyle .domesticForm, .intForm { padding:
   40px 0 }` (0,2,0) outranks a plain `.srCalc` (0,1,0) on the single-page
   (non-tabbed) forms, which carry both classes on the same element. */
.srCalc, .srCard { padding: 30px 32px !important; }
.srInlineResult { margin-top: 20px; padding: 0; overflow: hidden; animation: srRise var(--dur) var(--ease); }
/* !important: the base .srCalc/.srCard padding rule above is itself !important
   (needed to beat a legacy leak — see the comment on that rule), which would
   otherwise also defeat THIS flattening rule for a .srCard nested inside a
   .srCalc (the embedded Cargo/Quick forms), stacking double padding under the
   tab bar. Must win at every breakpoint since the base rule is !important there too. */
.srCalc .srCard, .srCalc .srCalc, .srCard .srCard { border: 0 !important; box-shadow: none !important; padding: 0 !important; margin: 0 !important; max-width: none !important; background: transparent !important; }
@keyframes srRise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* ── Split layout (0.5.0): form left, live results right ─────────────────
   Desktop: two columns, both in natural flow (no sticky, no static heights —
   removed 0.10.x). Below 940px it stacks (form first), and a sticky bottom
   summary bar (.srMobileBar) bridges the scroll gap.
   Narrow page variants (blog sidebar/default forms) opt out — their
   containers are too tight for two columns at ANY viewport width. */
.srSplit { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 0.92fr); gap: 26px; align-items: start; }
/* Both columns top-align (0.10.x). A vertical-center attempt on the form was
   tried and reverted: it detached the fields from the tab bar above (a void
   opened ABOVE the form too), which read as broken rather than balanced. A
   short form beside a long results list leaving blank space below it is
   normal, expected two-column-comparison UI — not something to fight with
   alignment tricks. If the empty space still needs addressing, that's a
   content decision (e.g. a benefits/trust panel filling the gap), not CSS. */
.srSplitForm { min-width: 0; }
.srSplitResults { min-width: 0; }
/* Tabbed mode: results top-aligns with the tab bar above it (0.10.x). Applies
   to all four tabs — .srCalcSub (the old intro sentence) is retired and
   force-hidden everywhere (`.srCalcSub { display: none !important; }` below),
   so on every tab the tab bar's own FIXED geometry (44px pill + 14px
   padding-bottom + 2/20px margins = 80px) is the only thing between .srTabs
   and .srSplit — nothing content-driven to misalign against. Pulling up by
   that same 78px (excluding the invisible 2px top margin) lands the card
   flush with the pills' visible top. Desktop only (two-column split starts
   at 941px, matching the mobile stack point). If .srCalcSub is ever
   un-hidden again, this rule needs to move to account for its height. */
@media (min-width: 941px) {
	.tabbingMainDiv .srSplitResults { margin-top: -78px; }
}
.srSplitResults .srInlineResult { margin-top: 0; max-width: none; box-shadow: none; }
/* Results still pending: an inviting placeholder instead of blank space. */
.srResultPlaceholder {
	border: 1.5px dashed var(--field-line); border-radius: var(--r-lg);
	padding: 40px 24px; text-align: center; color: var(--muted); background: var(--surface);
	font-size: var(--fs);
	display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.srResultPlaceholder .srEmptyIcon { margin-bottom: 12px; }
.srResultPlaceholder strong { display: block; color: var(--ink-2); font-size: var(--fs-in); margin-bottom: 4px; }
/* Auto-recalculation in flight over an EXISTING result: dim it (no layout
   shift, no jump back to skeleton) until the fresh numbers land. */
.srInlineResult.is-refreshing { opacity: 0.55; pointer-events: none; transition: opacity var(--dur) var(--ease); }
/* Sticky bottom summary (mobile/stacked): count + cheapest + jump-to-rates. */
.srMobileBar { display: none; }
@media (max-width: 940px) {
	.srSplit { grid-template-columns: 1fr; }
	/* No peek bar (0.11.1 — removed per feedback: the floating "N partners ·
	   View rates" bar read as confusing/unwanted chrome). .srMobileBar is no
	   longer given any mobile styling here, so it stays hidden under the
	   unconditional `.srMobileBar { display: none; }` base rule above. */

	/* Backdrop: single shared element, lazily appended to <body> by SrSheet.init()
	   (js/sheet.js) the first time any sheet on the page opens. */
	.srSheetBackdrop {
		position: fixed; inset: 0; z-index: 8000;
		background: rgba(11, 7, 87, 0.32);
		opacity: 0; pointer-events: none;
		transition: opacity var(--dur) var(--ease);
	}
	.srSheetBackdrop.is-visible { opacity: 1; pointer-events: auto; }

	/* Sheet mechanics (0.11.2 — sheet-only, per explicit feedback: NO inline
	   fallback card on mobile at all, only the sheet). .srSplitResults is
	   fixed and off-screen by DEFAULT at mobile widths — not just while a
	   class is toggled — sliding in only while .is-sheet-open is present.
	   Dismissing it (drag/backdrop/Escape) hides it again; there is no
	   "settled into normal page flow" fallback anymore and no peek bar to
	   reopen it — results are visible only while the sheet itself is open,
	   by design. A dismissed sheet reappears when the next result arrives
	   (openForLoading()/maybeAutoOpen() in js/sheet.js), not before. */
	.srSplitResults {
		position: fixed; left: 0; right: 0; bottom: 0; z-index: 8001;
		max-height: 85vh; max-height: 85dvh;
		background: #fff; border-radius: var(--r-card) var(--r-card) 0 0;
		box-shadow: var(--sh-card);
		overflow-y: auto; -webkit-overflow-scrolling: touch;
		padding: 22px 0 env(safe-area-inset-bottom);
		transform: translateY(100%);
		transition: transform 0.32s var(--ease);
		will-change: transform;
	}
	.is-sheet-open .srSplitResults { transform: translateY(0); }
	/* Drag handle — CSS-only, no markup change. (The actual drag gesture binds
	   to .srSplitResults itself in JS, gated by touch position near this
	   handle; pseudo-elements aren't a reliable direct touch-event target.) */
	.srSplitResults::before {
		content: ""; position: absolute; top: 10px; left: 50%;
		width: 40px; height: 4px; margin-left: -20px;
		background: var(--field-line); border-radius: 999px;
	}
	/* Body scroll lock while the sheet is open (toggled on <html> by JS). */
	html.srSheetLock, html.srSheetLock body { overflow: hidden; }
}
/* ── Results card (natural height) ───────────────────────────────────────
   No fixed height: every state — placeholder, skeleton, result list, empty
   state — sizes to its own content. The flex column keeps the head, mode
   tabs and Signup footer in document order while the row list grows
   naturally. A fixed 290px min/max-height here (0.13.x) was correct for the
   old compact table rows but is now WRONG for the 0.13.0 card redesign —
   each .srResultCard is taller than a table row ever was, so 290px clips
   after ~1.3 cards and the Signup footer sits flush against that clipped
   edge, reading as an overlap. Reverted to natural sizing to match the
   card content's real height. */
.srSplitResults .srInlineResult { display: flex; flex-direction: column; }
.srSplitResults .srInlineResult .srResultScroll {
    flex: 1 1 auto;
    min-height: 290px;
    max-height: 290px;
    overflow: auto;
}
/* Empty / no-service state fills the same space, vertically centred. */
.srSplitResults .srInlineResult > .srEmptyState,
.srSplitResults .srInlineResult > div > .srEmptyState {
	flex: 1 1 auto; min-height: 0; overflow-y: auto;
	display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.srSplitResults .srResultScroll .srEmptyState {
	min-height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center;
}
/* The result body wrapper (between head and foot) must be able to shrink. */
.srSplitResults .srInlineResult > div { min-height: 0; }
/* The single-page Domestic/International cards nest their mode tabs + row
   list inside an anonymous signup-toggle wrapper. It must be a shrinkable
   flex column too, or the row list inside it clips at the card edge with no
   scrollbar at all ("scroll not working"). :not([class]) keeps this off the
   head/foot/loader, which all carry classes or ids. */
.srSplitResults .srInlineResult > div:not([class]):not([id]) {
	display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0;
}
/* The display rules above (flex on empty states etc.) would otherwise beat
   the browser's [hidden] -> display:none — which made a JS-hidden "no data"
   block render alongside real rows. hidden always wins. */
.srCalc [hidden], .srCard [hidden], .srInlineResult [hidden] { display: none !important; }
/* Embedded Cargo/Quick under the tab bar: the Vue tabIntro line already
   introduces the tab, so the partial's own .srCalcSub would print the same
   sentence twice back-to-back. Standalone pages keep it. */
#tabBulk-tab .srCalcSub, #tabQuick-tab .srCalcSub { display: none !important; }

/* Narrow variants: single column always (container too tight). */
.singleForm .srSplit, .blogPageCalc .srSplit, .defaultForm .srSplit, .intDefaultForm .srSplit { display: block; }
.singleForm .srSplitResults .srInlineResult, .blogPageCalc .srSplitResults .srInlineResult,
.defaultForm .srSplitResults .srInlineResult, .intDefaultForm .srSplitResults .srInlineResult { margin-top: 20px; }
/* In-column placeholder is pointless when stacked directly under the form on
   narrow variants — the form itself is the "empty state". */
.singleForm .srResultPlaceholder, .blogPageCalc .srResultPlaceholder,
.defaultForm .srResultPlaceholder, .intDefaultForm .srResultPlaceholder { display: none; }

/* ── Tabs ───────────────────────────────────────────────────────────────── */
/* Pill-style navigation tabs (0.8.1). Active = brand-soft fill + brand text
   + brand-line border — the same "selected card" treatment as the rest of
   the system (NOT a solid brand fill: the two-tone brand icons would vanish
   on solid purple). */
.srTabs { display: flex; gap: 8px; margin: 2px 0 20px; padding-bottom: 14px; overflow-x: auto; box-shadow: 0 1px 0 var(--line); }
.srTabs .srTab {
	appearance: none; -webkit-appearance: none; flex: 0 0 auto; cursor: pointer;
	display: inline-flex; align-items: center; gap: 8px;
	padding: 0 18px; margin: 0; width: auto; min-height: 44px;
	font-size: var(--fs-in); font-weight: 600; line-height: 1; color: var(--muted);
	background: transparent; border: 1px solid transparent; border-radius: 999px;
	transition: color var(--dur) var(--ease), background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.srTabs .srTab:hover { color: var(--ink-2); background: var(--surface); border-color: var(--line); }
.srTabs .srTab.is-active { color: var(--brand); background: var(--brand-soft); border-color: var(--brand-line); }
.srTabs .srTab:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
/* One-line context sentence under the tab bar (and, for the same rhythm, above
   the field grid on the single-page forms) — gives every tab/form the same
   "anchor" at the top of the card regardless of how many fields it needs. */
/* 0.5.3: the intro sentence is retired everywhere (per request). Hidden via
   CSS rather than deleting the markup from four files, so restoring it later
   is a one-line change. */
.srCalcSub { display: none !important; }
/* Service icon — same size everywhere, always full brand colour. Each icon is
   a multi-tone SVG (purple + mint), so dimming it (a former opacity:0.55 on
   inactive tabs) faded the tones unevenly — green nearly vanished before
   purple did — making inactive tabs look like a different, washed-out icon
   set instead of the same mark at rest. Active vs. inactive is carried by
   text colour + underline only, so all four tabs read as one consistent set. */
.srTabIcon { width: 18px; height: 18px; flex: 0 0 auto; }

/* ── Field grid ─────────────────────────────────────────────────────────── */
.srCalcGrid { display: grid !important; grid-template-columns: 1fr 1fr; gap: 20px 24px; }
.srField { display: flex; flex-direction: column; gap: 8px; min-width: 0; margin: 0 !important; }
.srField--full { grid-column: 1 / -1; }
.srCalc > div:first-child:not(.srTabs) { display: block; } /* neutralise base flex on the form body */
.tabbingMainDiv .srSplitForm form { margin: 0 !important; }
/* !important: legacy `.calcComponentStyle .domesticForm label, .intForm label`
   (color:black; font-size:14px) is a same-or-higher-specificity type+class
   selector that would otherwise win and silently override this. */
.srFieldLabel {
	font-size: var(--fs-cap) !important; font-weight: 600 !important; color: var(--ink-2) !important;
	letter-spacing: 0; padding-left: 0 !important; margin-bottom: 0 !important;
}
.srReq { color: var(--brand); }
.srHint { color: var(--muted); font-weight: 500; }
/* Grouped controls (Dimensions, Payment Mode) use <fieldset>/<legend> for real
   group semantics — reset the browser's default fieldset chrome so it's
   visually identical to the plain .srField it replaces. */
fieldset.srField { border: 0; padding: 0; margin: 0 !important; min-width: 0; }
fieldset.srField legend.srFieldLabel { padding: 0; float: none; width: auto; }

/* Field-level success (valid, well-formed pincode). Additive signal only —
   doesn't change any validation logic, just reflects the SAME error state
   already tracked (well-formed + no current error message). */
.srField.is-valid .srInput.srInput { border-color: var(--ok) !important; padding-right: 38px !important; }
.srField.is-valid .srControl { position: relative; }
.srField.is-valid .srControl::after {
	content: "\2713"; position: absolute; right: 14px; top: 50%; transform: translateY(-50%);
	color: var(--ok); font-weight: 700; font-size: 14px; pointer-events: none;
}
.srField.is-valid .srControl--suffix::after { right: 62px; } /* clear the kg/₹ pill */

/* ── Inputs / selects (one control style) ───────────────────────────────── */
/* !important on every visual property: the host THEME styles bare
   input/select/button globally (often with its own !important), and any of
   those rules landing after ours in the cascade restyles the calculator.
   All state variants below (:focus, .has-error, .is-valid, --suffix) carry
   strictly higher specificity than this base, so marking the whole ladder
   !important preserves the existing state layering exactly. */
.srInput.srInput, .srField select.srInput {
	width: 100% !important; height: 50px !important; padding: 0 15px !important; margin: 0 !important;
	border: 1px solid var(--field-line) !important; border-radius: var(--r) !important;
	background: #ffffff !important; font-size: var(--fs-in) !important; color: var(--ink) !important;
	font-family: inherit !important; font-weight: 400; line-height: normal;
	text-transform: none !important; letter-spacing: normal !important;
	box-shadow: none !important; outline: none;
	transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.srInput.srInput::placeholder { color: var(--faint) !important; opacity: 1 !important; }
/* Entered data reads heavier than the placeholder hint, so a filled field is
   unmistakable at a glance rather than relying on colour contrast alone. */
.srInput.srInput:not(:placeholder-shown) { font-weight: 600; color: var(--ink) !important; }
.srInput.srInput:hover { border-color: #d3cfee !important; }
.srInput.srInput:focus { border-color: var(--brand) !important; box-shadow: 0 0 0 4px rgba(111, 87, 233, 0.13) !important; outline: none !important; }
.srInput.srInput:disabled, .srInput.srInput[readonly] { background: var(--tint) !important; color: var(--muted) !important; cursor: not-allowed; }
.srInput.srInput[type="number"]::-webkit-outer-spin-button,
.srInput.srInput[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.srInput.srInput[type="number"] { -moz-appearance: textfield; }
/* Doubled class: the hardened base's `.srField select.srInput` (0,2,1) sets the
   `background` SHORTHAND !important, and between !important declarations higher
   specificity wins — a bare `select.srInput` (0,1,1) loses and the chevron is
   wiped. `select.srInput.srInput` (0,2,1) ties the base and wins by source
   order, same hardening pattern as `.srInput.srInput` above. */
select.srInput.srInput {
	appearance: none; -webkit-appearance: none; padding-right: 40px !important;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath fill='%236b7086' d='M0 0h10L5 6z'/%3E%3C/svg%3E") !important;
	background-repeat: no-repeat !important; background-position: right 15px center !important;
}

/* ── Searchable select (country combobox) ──────────────────────────────────
   Replaces a native <select> that made the visitor scroll a 190+ country
   list. Same chevron affordance as select.srInput so it still reads as "a
   list opens here"; typing filters that same list in place. */
.srCombo { position: relative; }
.srCombo .srInput {
	appearance: none; -webkit-appearance: none; padding-right: 40px !important; cursor: text;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath fill='%236b7086' d='M0 0h10L5 6z'/%3E%3C/svg%3E") !important;
	background-repeat: no-repeat !important; background-position: right 15px center !important;
}
/* !important on the layout properties: the legacy tab-bar rule
   `.calcComponentStyle .tabbingMainDiv ul { display:flex; align-items:center;
   justify-content:center; padding:0 }` (0,2,1) outranks .srComboList (0,1,0)
   and matches this <ul> inside the tabbed calculator — flattening the
   dropdown into a centered horizontal row of country names (reported from
   production). Same leak class as the label/small/padding leaks fixed in
   0.4.3; hardened the same way. */
.srComboList {
	position: absolute; z-index: 20; top: calc(100% + 6px); left: 0; right: 0;
	display: block !important; align-items: normal !important; justify-content: normal !important;
	max-height: 260px; overflow-y: auto; margin: 0 !important; padding: 6px !important;
	list-style: none !important; background: #ffffff !important; border: 1px solid var(--field-line);
	border-radius: var(--r); box-shadow: var(--sh-card);
}
.srComboOption {
	display: block !important; margin: 0 !important; padding: 10px 12px !important;
	border-radius: var(--r-sm); text-align: left;
	font-size: var(--fs-in); color: var(--ink-2); line-height: 1.3; cursor: pointer;
}
.srComboOption.is-active, .srComboOption:hover { background: var(--brand-soft); color: var(--brand); }
.srComboEmpty { display: block !important; margin: 0 !important; padding: 10px 12px !important; font-size: var(--fs); color: var(--muted); }

/* ── Attached unit suffix (kg / rupee) — ONE style, defeats base dark pill ── */
.srControl { display: flex; align-items: stretch; }
/* !important mirrors the hardened base: its border/width/radius are now
   !important shorthands, so this variant's overrides must be too, or the
   suffix seam (no right border, flat right corners) would come back. */
.srControl--suffix .srInput.srInput { flex: 1 1 auto; width: auto !important; min-width: 0; border-radius: var(--r) 0 0 var(--r) !important; border-right: none !important; }
/* One suffix pill for kg / rupee. !important + static defeat the base
   `.domesticWeight > div span` (dark, 0,2,2) and `.shipmentValue span`
   (position:absolute) so every unit badge is an identical light attached pill. */
.srControl .srSuffix, .srSuffix.srSuffix {
	position: static !important; inset: auto !important; margin: 0 !important;
	display: flex !important; align-items: center; justify-content: center;
	flex: 0 0 auto; min-width: 48px; width: auto !important; height: auto !important;
	padding: 0 14px !important; line-height: 1;
	border: 1px solid var(--field-line) !important; border-left: none !important;
	border-radius: 0 var(--r) var(--r) 0 !important;
	background: var(--tint) !important; color: var(--muted) !important;
	font-size: var(--fs); font-weight: 600;
	transition: border-color var(--dur) var(--ease);
}
/* Focused compound control (input + attached kg/rupee pill) reads as ONE
   outlined unit. Without this, only the input got :focus's own glow, which
   stopped dead at the input's flat right edge — right where it meets the
   pill — instead of wrapping the whole control, so the ring looked cut off /
   broken. The glow now lives on the wrapper (sized+rounded to match the
   whole pill shape); the input's own glow is suppressed so there's no
   doubled/misaligned ring, and the suffix's border tints to match. */
.srControl--suffix:focus-within { box-shadow: 0 0 0 4px rgba(111, 87, 233, 0.13); border-radius: var(--r); }
.srControl--suffix:focus-within .srInput.srInput { box-shadow: none !important; }
.srControl--suffix:focus-within .srSuffix.srSuffix { border-color: var(--brand) !important; }

/* ── Dimensions — same control + same unit pill (cm) ────────────────────── */
.srDims { display: flex; align-items: center; gap: 6px; max-width: 300px; }
.srDims .srInput.srInput { text-align: center; padding: 0 8px !important; }
.srDims .srX { color: var(--faint); font-weight: 700; flex: 0 0 auto; }
.srDims .srUnit {
	flex: 0 0 auto; min-width: 52px; height: 50px; display: flex; align-items: center; justify-content: center;
	background: var(--tint); color: var(--muted); border: 1px solid var(--field-line); border-radius: var(--r);
	font-weight: 600; font-size: var(--fs);
}

/* ── Validation ─────────────────────────────────────────────────────────── */
/* !important: the legacy `.calcComponentStyle small { font-size:14px;
   padding-left:20px; color:red }` rule ties or beats this on specificity and
   would otherwise leak a 20px indent and the wrong red into every message. */
.srErr, .srBulkError {
	display: block;
	font-size: var(--fs-sm) !important; font-weight: 500; color: var(--err) !important;
	margin: 4px 0 0 !important; padding-left: 0 !important; line-height: 1.35;
}
/* An EMPTY message element takes no space at all — errors only occupy the
   layout when a message is actually present. (Zero-length Vue {{msg}} text
   nodes don't defeat :empty, so this covers the Vue slots too.) */
.srErr:empty, .srBulkError:empty { display: none !important; margin: 0 !important; }
.srField.has-error .srInput.srInput { border-color: var(--err) !important; }
.srField.has-error .srInput.srInput:focus { box-shadow: 0 0 0 4px rgba(229, 72, 77, 0.14) !important; }

/* ── Radio group (the design system's ONE radio style, 0.8.0) ─────────────
   Replaces the former segmented pill (Payment Mode) and the Quick vehicle
   cards — one classic radio-button style everywhere: real radio inputs
   (native keyboard behaviour + "N of M" screen-reader announcement) with a
   visible dot drawn on the sibling span (checked-sibling selector, not
   :has(), for broad support). min-height 50px matches the input height so a
   radio row pairs level with a text field in the grid. */
.srRadioGroup { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 28px; min-height: 50px; }
.srRadio {
	position: relative; display: inline-flex !important; align-items: center; gap: 9px;
	cursor: pointer; min-height: 44px; margin: 0;
	font-size: var(--fs); font-weight: 600; color: var(--ink-2);
}
.srRadio input[type="radio"] {
	position: absolute; inset: 0; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer;
}
.srRadioDot {
	flex: 0 0 auto; width: 18px; height: 18px; border-radius: 50%;
	border: 1.5px solid var(--field-line); background: #fff; position: relative;
	transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.srRadioDot::after {
	content: ""; position: absolute; inset: 3px; border-radius: 50%;
	background: var(--brand); transform: scale(0); transition: transform var(--dur) var(--ease);
}
.srRadio:hover .srRadioDot { border-color: var(--brand-line); }
.srRadio input[type="radio"]:checked ~ .srRadioDot { border-color: var(--brand); }
.srRadio input[type="radio"]:checked ~ .srRadioDot::after { transform: scale(1); }
.srRadio input[type="radio"]:checked ~ .srRadioLabel { color: var(--ink); }
.srRadio input[type="radio"]:focus-visible ~ .srRadioDot { outline: 2px solid var(--brand); outline-offset: 2px; }
.srRadioLabel { transition: color var(--dur) var(--ease); }
.srRadioLabel .srHint { font-weight: 500; }

/* ── Buttons (one hierarchy: primary / ghost / link) ────────────────────── */
.srCalcActions { display: flex; align-items: center; gap: 14px; margin-top: 24px; }
/* !important for the same reason as the input block above: host themes style
   bare <button> globally (background, radius, text-transform, padding), often
   with their own !important. Primary/ghost/hover/disabled all sit at higher
   specificity than this base, so the state ladder is preserved. */
.srBtn.srBtn {
	appearance: none; -webkit-appearance: none; border: 1.5px solid transparent !important; cursor: pointer; margin: 0 !important; width: auto !important;
	min-height: 44px !important; font-family: inherit !important; font-size: var(--fs-in) !important; font-weight: 700 !important; line-height: 1 !important; border-radius: var(--r) !important;
	text-decoration: none !important; text-align: center; text-transform: none !important; letter-spacing: normal !important;
	display: inline-flex; align-items: center; justify-content: center;
	transition: background var(--dur) var(--ease), box-shadow var(--dur) var(--ease), color var(--dur) var(--ease),
		border-color var(--dur) var(--ease), transform 0.06s var(--ease);
}
.srBtn.srBtn:active { transform: translateY(1px); }
.srBtn-primary.srBtn-primary { padding: 14px 30px !important; color: #fff !important; background: linear-gradient(180deg, #7a63f0, #6a51e6) !important; box-shadow: var(--sh-btn) !important; }
.srBtn-primary.srBtn-primary:hover { background: linear-gradient(180deg, #7057ef, #5f47e0) !important; box-shadow: 0 10px 26px rgba(111, 87, 233, 0.38) !important; }
.srBtn-primary.srBtn-primary:disabled { background: #cfcae8 !important; color: #fff !important; box-shadow: none !important; cursor: not-allowed; }
.srBtn-ghost.srBtn-ghost { padding: 14px 22px !important; background: none !important; color: var(--muted) !important; font-weight: 600 !important; }
.srBtn-ghost.srBtn-ghost:hover { color: var(--ink-2) !important; }
.srBtnSpacer { margin-left: auto; }
.srBtnSpin, .srBulkSpinner {
	display: inline-block; width: 22px; height: 22px; box-sizing: border-box;
	border: 3px solid rgba(111, 87, 233, 0.22); border-top-color: var(--brand);
	border-radius: 50%; animation: srSpin 0.7s linear infinite;
}
@keyframes srSpin { to { transform: rotate(360deg); } }

/* ── Results ────────────────────────────────────────────────────────────── */
.srInlineResultHead {
	display: flex; align-items: center; justify-content: space-between; gap: 12px;
	padding: 14px 24px; background: var(--surface); border-bottom: 1px solid var(--line);
}
.srInlineResultTitle { font-size: var(--fs-h); font-weight: 700; color: var(--ink); letter-spacing: -0.01em; }
.srInlineResultNote { font-size: var(--fs-sm); color: var(--muted); }
.srBackLink.srBackLink {
	appearance: none; -webkit-appearance: none; border: 0; background: none; cursor: pointer; margin: 0; width: auto;
	display: inline-flex; align-items: center; min-height: 44px; padding: 4px 0;
	color: var(--brand); font-size: var(--fs-cap); font-weight: 600; font-family: inherit;
	transition: color var(--dur) var(--ease);
}
.srBackLink.srBackLink::before { content: "\2190"; margin-right: 6px; }
.srBackLink.srBackLink:hover { color: var(--brand-2); }

/* Mode tabs (All / Air / Surface) — ONE size everywhere, ≥44px tap target */
/* Two-row toolbar (0.9.1): row 1 = title | summary, row 2 = filter chips |
   sort. The ::after pseudo is a full-width flex break; order properties put
   every li on its intended row — no markup restructure needed. */
.srModeTabs { display: flex !important; flex-wrap: wrap; gap: 8px; row-gap: 10px; align-items: center; list-style: none !important; margin: 0 !important; padding: 12px 24px 10px !important; justify-content: flex-start !important; background: var(--surface); }
.srModeTabs::after { content: ""; flex-basis: 100%; order: 2; height: 0; }
.srModeTabs .srBarTitle { order: 0; margin-right: 0; }
.srModeTabs .srBarSummary { order: 1; margin-left: auto !important; }
.srModeTabs .srModeChip { order: 3; }
.srModeTabs .srSortGroup { order: 4; margin-left: auto !important; }
.srModeTabs li { list-style: none !important; margin: 0 !important; }
/* !important: the result containers keep the legacy `dataTabs` class (the
   OTP funnel selects on it), and `.calcComponentStyle .dataTabs ul li a`
   (0,2,3) styles these links as bordered 6px-radius boxes with its own
   padding — beating .srModeTabs a (0,1,1) and sizing every tab differently.
   Pin the pill look so all three mode tabs render identically. */
.srModeTabs a {
	display: inline-flex !important; align-items: center; justify-content: center; min-height: 32px;
	min-width: 64px; padding: 5px 14px !important; border-radius: 999px !important;
	font-size: var(--fs-cap) !important; font-weight: 600 !important; margin: 0 !important;
	color: var(--muted) !important; text-decoration: none !important;
	border: 1px solid transparent !important; background: var(--tint) !important; text-transform: capitalize;
	transition: background var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
/* Mode icons (Surface = truck, Air = plane) — inline SVG, no markup change
   needed beyond the icon itself since .srModeTabs a is already inline-flex;
   currentColor makes them follow the pill's own text color (muted/active). */
.srModeTabs a svg { width: 14px; height: 14px; flex: 0 0 auto; margin-right: 5px; }
.srModeTabs a:hover { background: var(--brand-soft) !important; color: var(--ink-2) !important; }
.srModeTabs a:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.srModeTabs a.active { background: var(--brand) !important; color: #fff !important; border-color: var(--brand) !important; }
@media (max-width: 1024px) {
	.srModeTabs a { min-height: 44px; }
}
/* Compact shipping summary living IN the header band: count + from-price on
   the filter bar's empty right side (Vue fills it reactively; Cargo/Quick via
   their renderers). On filterless tables it renders as its own slim band. */
.srModeTabs .srBarTitle, .srBarTitle { display: flex; align-items: center; font-size: var(--fs-cap); font-weight: 700; color: var(--ink); margin-right: 10px; white-space: nowrap; }
.srModeTabs .srBarSummary { margin-left: auto; display: flex; align-items: center; font-size: var(--fs-sm); font-weight: 600; color: var(--muted); white-space: nowrap; }
.srModeTabs .srBarSummary strong { color: var(--ink); font-weight: 700; margin-left: 4px; }
.srResultSummaryBar { background: var(--surface); padding: 10px 24px; font-size: var(--fs-sm); font-weight: 600; color: var(--muted); display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
/* Sort control (0.9.0): compact text-buttons in the header band. !important
   on the button chrome per the theme-hardening convention (§ CSS rules). */
.srSortGroup {
	display: inline-flex; align-items: center; gap: 2px;
	font-size: var(--fs-sm); font-weight: 600; color: var(--muted); white-space: nowrap;
	background: var(--tint); border-radius: 999px; padding: 3px 4px 3px 12px;
}
.srResultSummaryBar .srSortGroup { margin-left: 0; }
.srSortGroup .srSortBtn {
	appearance: none; -webkit-appearance: none; cursor: pointer; font-family: inherit;
	border: 0 !important; background: none !important; margin: 0 0 0 4px !important;
	padding: 5px 10px !important; min-height: 0; border-radius: 999px !important;
	font-size: var(--fs-sm) !important; font-weight: 600 !important; color: var(--muted) !important; line-height: 1.2;
	transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.srSortGroup .srSortBtn:hover { color: var(--ink-2) !important; }
.srSortGroup .srSortBtn.active { color: var(--brand) !important; background: #fff !important; box-shadow: 0 1px 4px rgba(11, 7, 87, 0.10); }
.srSortGroup .srSortBtn:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
/* With the sort group owning margin-left:auto, the summary follows it. */
.srModeTabs .srBarSummary { margin-left: 16px; }
.srResultSummaryBar strong { color: var(--ink); font-weight: 700; }

/* Result rows rendered as cards (table markup kept, styled as separated cards) */
/* Side padding 24px matches the card head/foot so rows align with the title
   (was 20px — a 4px misalignment against every other card section). */
.srResultScroll { padding: 12px 24px; }
.srInlineResult table { width: 100% !important; border-collapse: separate !important; border-spacing: 0 8px !important; margin: 0 !important; table-layout: fixed; }
.srInlineResult tbody td:first-child { width: 42%; }
.srInlineResult tbody td:last-child { width: 28%; }
/* Single header (0.7.3): the chips+summary band above the table IS the one
   visible header — the column-label row is screen-reader-only (the columns
   self-describe: courier names, "2 Days", ₹ prices). Keeping the <thead> in
   the markup preserves table semantics for assistive tech. All props
   !important so per-calculator th overrides (e.g. Quick's id-specific ones)
   can't resurrect the visual row. */
.srInlineResult thead th {
	position: absolute !important; width: 1px !important; height: 1px !important;
	padding: 0 !important; margin: -1px !important; border: 0 !important;
	overflow: hidden !important; clip: rect(0 0 0 0); white-space: nowrap;
	background: transparent !important; box-shadow: none !important;
}
/* Small non-shouting annotation inside a column header (e.g. "incl. GST"). */
.srThNote { font-weight: 500; text-transform: none; letter-spacing: 0; color: var(--faint); font-size: 10.5px; margin-left: 4px; }
.srInlineResult thead th:last-child, .srInlineResult tbody td:last-child { text-align: right; }
.srInlineResult tbody td {
	background: #fff; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
	padding: 15px 16px; font-size: var(--fs); line-height: 22px; color: var(--muted); font-variant-numeric: tabular-nums;
	transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.srInlineResult tbody td:first-child { border-left: 1px solid var(--line); border-radius: var(--r) 0 0 var(--r); font-weight: 600; color: var(--ink); }
.srInlineResult tbody td:last-child { border-right: 1px solid var(--line); border-radius: 0 var(--r) var(--r) 0; }
.srInlineResult tbody tr { animation: srRise var(--dur) var(--ease); }
.srInlineResult tbody tr:hover td { border-color: var(--brand-line); background: var(--surface); }
.srInlineResult tbody tr.srBest td { border-color: var(--brand-line); background: var(--brand-soft); }
.srInlineResult tbody tr.srBest td:first-child { border-left: 3px solid var(--brand); padding-left: 14px; }
.srInlineResult .srRate { font-weight: 800; color: var(--ink); font-size: var(--fs-h); letter-spacing: -0.01em; }

/* ── Result cards (0.13.0) ──────────────────────────────────────────────────
   Replaces the table-row layout above for all four calculators: a two-tier
   card (logo/name/mode badge on top, Pickup By / TAT / Rate on the bottom)
   instead of a single row of cells — the table markup can't express that
   two-tier structure, so this is a genuinely different DOM shape (.srResultList
   of .srResultCard divs), not a restyle of the existing <table>. No radio/
   selection control by design. Every element here degrades gracefully:
   .srResultCardLogo falls back to a generic icon when no real logo URL
   exists (Domestic/International/Quick have none), and .srResultCardBadge
   is simply omitted where a calculator has no mode concept (only Cargo has
   Surface/Air) — never fabricated. */
.srResultList { display: flex; flex-direction: column; gap: 10px; }
.srResultCard {
	border: 1px solid var(--line); border-radius: var(--r-lg); background: #fff;
	padding: 14px 16px; display: flex; flex-direction: column; gap: 12px;
	animation: srRise var(--dur) var(--ease);
	transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.srResultCard:hover { border-color: var(--brand-line); background: var(--surface); }
.srResultCard.srBest { border-color: var(--brand-line); background: var(--brand-soft); }

.srResultCardTop { display: flex; align-items: center; gap: 12px; }
.srResultCardLogo {
	flex: 0 0 auto; width: 40px; height: 40px; border-radius: var(--r-sm);
	background: var(--tint); display: flex; align-items: center; justify-content: center;
	overflow: hidden;
}
.srResultCardLogo img { width: 100%; height: 100%; object-fit: contain; }
.srResultCardLogo svg { width: 20px; height: 20px; color: var(--muted); }
.srResultCardName {
	flex: 1 1 auto; min-width: 0; font-weight: 700; color: var(--ink);
	font-size: var(--fs-in); text-transform: uppercase; letter-spacing: 0.01em;
	overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Optional second line under the name (e.g. International's "charged
   weight") — only present when a calculator has that extra per-row context.
   Wrap .srResultCardName + .srResultCardSub in .srResultCardNameWrap to
   stack them; calculators without a subtitle skip the wrapper entirely and
   .srResultCardName sits directly in .srResultCardTop as usual. */
.srResultCardNameWrap { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.srResultCardNameWrap .srResultCardName { flex: 0 0 auto; }
.srResultCardSub { font-size: var(--fs-xs); font-weight: 500; color: var(--muted); text-transform: none; letter-spacing: 0; }
.srResultCardBadge {
	flex: 0 0 auto; font-size: 10.5px; font-weight: 700; letter-spacing: 0.03em;
	text-transform: uppercase; padding: 4px 10px; border-radius: 999px;
	background: var(--ok-bg); color: var(--ok);
}
.srResultCardBadge--air { background: var(--info-bg); color: var(--info); }

/* align-items: flex-start, not flex-end — the Rate column is often TALLER
   than Pickup By/TAT (it can carry an extra "Cheapest" chip below its
   value), and flex-end bottom-aligns each item by its OWN total height,
   which floats the Rate label up out of line with the other two labels.
   flex-start keeps all three labels flush on one line regardless. */
.srResultCardMeta { display: flex; align-items: flex-start; gap: 16px; padding-top: 12px; border-top: 1px solid var(--line); }
.srResultCardMetaItem { flex: 1 1 0; min-width: 0; }
.srResultCardMetaItem--rate { flex: 0 0 auto; text-align: right; }
.srResultCardMetaLabel {
	display: block; font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em;
	text-transform: uppercase; color: var(--faint); margin-bottom: 4px;
}
.srResultCardMetaValue { display: block; font-size: var(--fs); font-weight: 700; color: var(--ink); }
.srResultCardMetaItem--rate .srResultCardMetaValue { font-size: var(--fs-h); font-weight: 800; letter-spacing: -0.01em; }

.srResultFoot {
	padding: 14px 24px; border-top: 1px solid var(--line); background: var(--surface);
	display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
}
.srFootText { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.srFootTitle { font-size: var(--fs-in); font-weight: 800; color: var(--ink); letter-spacing: -0.01em; }
.srFootNote { display: block; font-size: var(--fs-sm); color: var(--muted); margin: 0; }
/* "Create a free account to book at these rates" — dropped on mobile per
   feedback; "Ready to ship?" + the Signup Now button stay, just not the
   descriptive subtitle underneath. MUST stay after the base .srFootNote
   rule above — equal specificity, so an earlier media-query copy loses the
   cascade tie to this later unscoped rule regardless of viewport (this bit
   a first attempt: the override was placed in an earlier @media block and
   was silently never applying). */
@media (max-width: 940px) {
	.srFootNote { display: none; }
}
.srResultFoot a, .srResultFoot .srBtn-primary, .srResultFoot .js-srOpenSignup {
	display: inline-flex; align-items: center; justify-content: center; padding: 13px 26px; border: 0; border-radius: var(--r);
	text-decoration: none; cursor: pointer; font-family: inherit; font-weight: 700; font-size: var(--fs);
	color: #fff; background: linear-gradient(180deg, #7a63f0, #6a51e6); box-shadow: var(--sh-btn);
	transition: box-shadow var(--dur) var(--ease), transform 0.06s var(--ease);
}
.srResultFoot a:hover, .srResultFoot .js-srOpenSignup:hover { box-shadow: 0 10px 26px rgba(111, 87, 233, 0.38); }
.srResultFoot a:active { transform: translateY(1px); }
.srNoData { display: block; padding: 44px 24px; text-align: center; color: var(--muted); font-size: var(--fs-in); }

/* ── Empty state ────────────────────────────────────────────────────────────
   Richer "no options" state: icon + heading + the API's own message + concrete
   next steps, instead of one flat line of text. Sits where the results table
   would otherwise render (same card, same padding rhythm). */
.srEmptyState { padding: 40px 24px 36px; text-align: center; }
.srEmptyIcon {
	width: 56px; height: 56px; margin: 0 auto 16px; border-radius: 50%;
	background: var(--tint); display: flex; align-items: center; justify-content: center; color: var(--muted);
}
.srEmptyIcon svg { width: 26px; height: 26px; }
.srEmptyTitle { font-size: var(--fs-h) !important; font-weight: 700 !important; color: var(--ink) !important; margin: 0 0 6px !important; }
.srEmptyMsg { font-size: var(--fs); color: var(--muted); margin: 0 0 18px; max-width: 420px; margin-left: auto; margin-right: auto; }
.srEmptyList { list-style: none !important; margin: 0 auto !important; padding: 0 !important; display: inline-flex; flex-direction: column; gap: 8px; text-align: left; }
.srEmptyList li { font-size: var(--fs-cap); color: var(--ink-2); margin: 0 !important; padding-left: 20px !important; position: relative; list-style: none !important; }
.srEmptyList li::before { content: ""; position: absolute; left: 4px; top: 9px; width: 5px; height: 5px; border-radius: 50%; background: var(--brand); }

/* ── Skeleton loader ─────────────────────────────────────────────────────────
   Shown in place of the result card while a request is in flight, sized to
   match real result rows so the real results replace it with no layout shift.
   Respects prefers-reduced-motion (see below) by falling back to a static tint. */
.srSkeletonCard { padding: 20px 24px 24px; }
.srSkelHead { height: 20px; width: 140px; border-radius: 6px; margin-bottom: 18px; }
.srSkelRow { height: 58px; border-radius: var(--r); margin-bottom: 10px; }
.srSkelHead, .srSkelRow {
	background: linear-gradient(100deg, var(--tint) 30%, #eceaf9 45%, var(--tint) 60%);
	background-size: 200% 100%; animation: srShimmer 1.4s ease-in-out infinite;
}
@keyframes srShimmer { 0% { background-position: 160% 0; } 100% { background-position: -60% 0; } }

/* ── Tablet (768–1024px) ────────────────────────────────────────────────────
   The 2-column grid, tabs, and result rows are unchanged from desktop at this
   width, but the card gets a touch less padding and the mode-tab row wraps
   cleanly so nothing crowds the edges on an iPad-portrait viewport. */
@media (max-width: 1024px) and (min-width: 641px) {
	.srCalc, .srCard { padding: 26px 24px !important; }
	.srCalcGrid { gap: 20px; }
	.srModeTabs { flex-wrap: wrap; }
}

/* ── Mobile ─────────────────────────────────────────────────────────────── */
@media (max-width: 640px) {
	.srCalc, .srCard { padding: 22px 18px !important; border-radius: var(--r-lg); }
	.srCalcGrid { grid-template-columns: 1fr; gap: 18px; }
	.srCalcActions { flex-wrap: wrap; }
	.srBtn-primary.srBtn-primary { flex: 1 1 auto; }
	.srInlineResultHead, .srModeTabs, .srResultFoot { padding-left: 16px; padding-right: 16px; }
	/* Mobile toolbar (0.10.1): the desktop right-alignments (summary + sort
	   via margin-left auto) produce ragged right-hanging rows when the band
	   wraps — stack everything left instead: title, summary, chips, sort. */
	.srModeTabs { row-gap: 8px; }
	.srModeTabs .srBarSummary { margin-left: 0 !important; flex-basis: 100%; }
	.srModeTabs .srSortGroup { margin-left: 0 !important; }
	.srResultSummaryBar { flex-direction: column; align-items: flex-start; gap: 8px; }
	.srResultScroll { padding-left: 12px; padding-right: 12px; }
	.srInlineResult tbody td { padding: 13px; }
	.srModeTabs { flex-wrap: wrap; }
	.srSkeletonCard { padding: 16px 16px 20px; }
	/* Denser header band (0.11.0): the desktop sizing (44px tap targets, 18px
	   title, 24px padding) reads as oversized in a compact 375px-wide sheet.
	   Tightened here, not by editing the desktop rules above — this whole
	   block is already phone-only. Chips stay a real, if smaller, tap target
	   (34px) rather than shrinking to the 44px-at-1024px rule's exact opposite. */
	.srInlineResultHead { padding-top: 12px; padding-bottom: 12px; }
	.srInlineResultTitle { font-size: var(--fs-in); }
	.srModeTabs { padding-top: 10px !important; padding-bottom: 8px !important; gap: 6px; }
	.srModeTabs a {
		min-height: 34px !important; min-width: 0; padding: 4px 12px !important;
		font-size: var(--fs-sm) !important;
	}
	/* Filter chips vs. sort control (0.11.0): these read as ONE undifferentiated
	   row of pills at phone width — nothing marks "All/Surface/Air" (a filter)
	   as a different kind of control from "Sort · Price · Delivery". Two fixes:
	   1. Force the sort group onto its OWN row (flex-basis:100%, same trick
	      .srBarSummary already uses above) instead of crowding the same line.
	   2. Make "Sort" read as a plain label, not a fourth pill: capitalized,
	      tracked, and NOT bold/tinted like the chips — text-transform is reset
	      on the two buttons so only the bare "Sort" text gets the label
	      treatment, not "Price"/"Delivery" themselves. */
	.srModeTabs .srSortGroup {
		flex-basis: 100%; margin-left: 0 !important; margin-top: 2px;
		padding: 6px 3px 6px 0; background: none;
		text-transform: uppercase; letter-spacing: 0.05em; font-size: var(--fs-xs) !important;
	}
	.srSortGroup .srSortBtn {
		text-transform: none; letter-spacing: normal;
		padding: 4px 10px !important; font-size: var(--fs-xs) !important;
		background: var(--tint) !important;
	}
	.srSortGroup .srSortBtn.active { background: #fff !important; }
	/* !important: mirrors the base .srErr rule's fight with the legacy
	   `.calcComponentStyle small` styles — keeps the slot hidden on mobile.
	   The red field border (.srField.has-error) still signals the error. */
	.srErr { display: none !important; }
}

/* ── Reduced motion ─────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
	.srInlineResult, .srBtn, .srBtnSpin, .srBulkSpinner, .srInput.srInput, .srTab, .srModeTabs a, .srRadioDot, .srRadioDot::after, .srRadioLabel,
	.srSkelHead, .srSkelRow { animation: none !important; transition: none !important; }
	.srSkelHead, .srSkelRow { background: var(--tint); }
	/* Bottom sheet: no slide/fade, just an instant show/hide. */
	.srSplitResults, .srSheetBackdrop, .srMobileBar .srMobileBarBtn::after { transition: none !important; }
}
