/*
 * tap-system.css — the DIVSA design system layer.
 *
 * WHY THIS FILE EXISTS
 * --------------------
 * The frontend grew section by section, and each section brought its own
 * geometry. Audited live on the homepage at 1425px, 2026-08-28:
 *
 *   card border-radius   7 distinct values   12 / 14 / 16 / 20 / 22 / 24 / 999
 *   card box-shadow      7 distinct values   0 2px 10px … 0 16px 40px
 *   card padding         6 distinct values   18px 20px 10px, 14px 16px, …
 *   button height        4 distinct values   44 / 48 / 50 / 99
 *   button radius        4 distinct values   4 / 12 / 14 / 999
 *   button typography    6 distinct values   14/700, 16/400, 12/800, …
 *   eyebrow tracking     2 distinct values   1.92px / 1.2px
 *   section title        2 distinct values   26px / 24px
 *   icon size            6 distinct values   14 / 20 / 22 / 26 / 30 / 34
 *
 * None of those values is wrong on its own. Having seven of each is the
 * problem: it is what makes a page read as assembled rather than designed.
 *
 * This file is a SCALE, not a patch. It defines one set of tokens and maps
 * the existing component classes onto them. It is registered last so it is
 * the single place geometry is decided; a component stylesheet keeps owning
 * its layout and behaviour, and stops owning its own radius and elevation.
 *
 * It deliberately does NOT touch brand colour. --tap-purple, --tap-marigold
 * and the rest stay exactly as the operator set them.
 *
 * @package DIVSA_OS
 * @since   8.6.29
 */

/* ==========================================================================
   1. TOKENS
   ========================================================================== */
.tap-root,
.tap-home-root,
.tap-chrome-header,
.tap-chrome-footer,
.tap-app-shell{
	/* --- Radius: four steps, not seven ------------------------------------
	   sm  chips, badges, small controls
	   md  buttons, inputs, icon tiles
	   lg  cards, sheets, media
	   pill fully rounded controls                                        */
	--ds-radius-sm: 10px;
	/*
	 * Control corner: also an operator setting (--tap-btn-radius, from Brand
	 * & Theme). This site has it at 4px; hardcoding 14px here would have
	 * quietly overruled that choice on every button while leaving the store's
	 * own buttons at 4px — inconsistency introduced by the layer meant to
	 * remove it. Same principle as --ds-radius-lg: derive, do not decide.
	 */
	--ds-radius-md: var(--tap-btn-radius, 14px);
	/*
	 * The card corner is an OPERATOR setting, not a designer's constant:
	 * TAP_Layout already emits --tap-card-radius from Cards & Layout →
	 * card radius. Deriving from it means the service card and the store
	 * card land on the same number because they read the same control —
	 * consistency by construction rather than by two hardcoded values that
	 * happen to agree until someone edits one of them.
	 */
	--ds-radius-lg: var(--tap-card-radius, 18px);
	--ds-radius-pill: 999px;

	/* --- Elevation: three steps, all restrained ---------------------------
	   The audit found a 0 16px 40px shadow on a 134px card — an elevation
	   deeper than the object casting it. Premium surfaces sit close to the
	   page; they do not hover above it.                                   */
	--ds-shadow-0: none;
	--ds-shadow-1:
		0 1px 2px color-mix(in srgb, var(--tap-ink) 5%, transparent);
	--ds-shadow-2:
		0 1px 2px color-mix(in srgb, var(--tap-ink) 4%, transparent),
		0 4px 14px color-mix(in srgb, var(--tap-ink) 4%, transparent);
	--ds-shadow-3:
		0 2px 4px color-mix(in srgb, var(--tap-ink) 5%, transparent),
		0 10px 26px color-mix(in srgb, var(--tap-ink) 6%, transparent);

	/* --- Space: one 4px-based scale --------------------------------------- */
	--ds-space-1: 4px;
	--ds-space-2: 8px;
	--ds-space-3: 12px;
	--ds-space-4: 16px;
	--ds-space-5: 20px;
	--ds-space-6: 24px;
	--ds-space-8: 32px;

	/* --- Controls ---------------------------------------------------------
	   48px on a phone is the comfortable primary height the brief asks for;
	   44px is the floor for secondary and inline controls.                */
	--ds-control-h: 48px;
	--ds-control-h-sm: 44px;
	--ds-control-pad-x: 22px;

	/* --- Icons: three sizes ----------------------------------------------- */
	--ds-icon-sm: 16px;
	--ds-icon-md: 20px;
	--ds-icon-lg: 26px;

	/* --- Focus ------------------------------------------------------------ */
	--ds-focus: 0 0 0 3px color-mix(in srgb, var(--tap-primary) 30%, transparent);
}

/* ==========================================================================
   2. BUTTONS — one system, three roles

   Primary    booking, payment, the one conversion action on a screen
   Secondary  view details, support, explore — soft/outline
   Tertiary   see all, learn more — a text link with a target area

   Existing component classes are mapped onto these rather than renamed, so
   no template changes and no second button vocabulary.
   ========================================================================== */

/* -- shared shape -------------------------------------------------------- */
.tap-root.tap-root .tap-btn,
.tap-root.tap-root .tap-cta,
.tap-root.tap-root .tap-fcard-cta,
.tap-root.tap-root .tap-sam-card-add,
.tap-chrome-header.tap-chrome-header .tap-chrome-cta,
.tap-root.tap-root .tap-vfilter__go,
.tap-home-root.tap-home-root .tap-vertical-empty__link{
	display:inline-flex; align-items:center; justify-content:center;
	gap:var(--ds-space-2);
	min-block-size:var(--ds-control-h);
	padding-inline:var(--ds-control-pad-x);
	border-radius:var(--ds-radius-md);
	border:1px solid transparent;
	font-family:var(--tap-font-body);
	font-size:15px;
	font-weight:700;
	line-height:1.1;
	letter-spacing:.005em;
	text-decoration:none;
	cursor:pointer;
	/* A control must never be the thing that makes a card taller. */
	max-inline-size:100%;
	transition:
		background-color var(--tap-motion-quick, 160ms) var(--tap-ease-standard, ease),
		border-color var(--tap-motion-quick, 160ms) var(--tap-ease-standard, ease),
		color var(--tap-motion-quick, 160ms) var(--tap-ease-standard, ease),
		transform 90ms var(--tap-ease-standard, ease),
		box-shadow var(--tap-motion-quick, 160ms) var(--tap-ease-standard, ease);
}

/* Icons inside a button share one size and never shrink. */
.tap-root.tap-root .tap-btn svg,
.tap-root.tap-root .tap-cta svg,
.tap-root.tap-root .tap-fcard-cta svg,
.tap-chrome-header.tap-chrome-header .tap-chrome-cta svg{
	inline-size:var(--ds-icon-md); block-size:var(--ds-icon-md);
	flex:0 0 auto;
}

/* -- primary ------------------------------------------------------------- */
.tap-root.tap-root .tap-btn-primary,
.tap-root.tap-root .tap-fcard-cta,
.tap-root.tap-root .tap-sam-card-add,
.tap-chrome-header.tap-chrome-header .tap-chrome-cta,
.tap-root.tap-root .tap-vfilter__go,
.tap-home-root.tap-home-root .tap-vertical-empty__link.is-primary{
	background:var(--tap-cta, var(--tap-primary));
	color:var(--tap-cta-text, #fff);
	box-shadow:var(--ds-shadow-1);
}
.tap-root.tap-root .tap-btn-primary:hover,
.tap-root.tap-root .tap-fcard-cta:hover,
.tap-root.tap-root .tap-sam-card-add:hover,
.tap-chrome-header.tap-chrome-header .tap-chrome-cta:hover,
.tap-root.tap-root .tap-vfilter__go:hover{
	background:color-mix(in srgb, var(--tap-cta, var(--tap-primary)) 88%, var(--tap-ink));
	box-shadow:var(--ds-shadow-2);
}

/* -- secondary ----------------------------------------------------------- */
.tap-root.tap-root .tap-btn-ghost,
.tap-root.tap-root .tap-btn-secondary,
.tap-home-root.tap-home-root .tap-vertical-empty__link{
	background:var(--tap-card, #fff);
	color:var(--tap-ink);
	border-color:var(--tap-line);
	box-shadow:none;
}
.tap-root.tap-root .tap-btn-ghost:hover,
.tap-root.tap-root .tap-btn-secondary:hover,
.tap-home-root.tap-home-root .tap-vertical-empty__link:hover{
	border-color:var(--tap-primary);
	color:var(--tap-primary);
	background:color-mix(in srgb, var(--tap-primary) 5%, var(--tap-card, #fff));
}

/* -- tertiary — the "See all ›" links ------------------------------------ */
.tap-root.tap-root .tap-sec-action,
.tap-home-root.tap-home-root .tap-sec-action{
	display:inline-flex; align-items:center; gap:6px;
	min-block-size:var(--ds-control-h-sm);
	padding-inline:var(--ds-space-2);
	border-radius:var(--ds-radius-sm);
	font-family:var(--tap-font-body);
	font-size:14px; font-weight:700;
	color:var(--tap-primary);
	text-decoration:none;
	background:none; border:0;
}
.tap-root.tap-root .tap-sec-action:hover{
	color:color-mix(in srgb, var(--tap-primary) 84%, var(--tap-ink));
	background:color-mix(in srgb, var(--tap-primary) 6%, transparent);
}

/* -- states -------------------------------------------------------------- */
.tap-root.tap-root .tap-btn:active,
.tap-root.tap-root .tap-cta:active,
.tap-root.tap-root .tap-fcard-cta:active,
.tap-root.tap-root .tap-sam-card-add:active,
.tap-chrome-header.tap-chrome-header .tap-chrome-cta:active{
	/* A press should be felt, not watched. */
	transform:translateY(1px);
	box-shadow:var(--ds-shadow-1);
}
.tap-root.tap-root .tap-btn:focus-visible,
.tap-root.tap-root .tap-cta:focus-visible,
.tap-root.tap-root .tap-fcard-cta:focus-visible,
.tap-root.tap-root .tap-sam-card-add:focus-visible,
.tap-root.tap-root .tap-sec-action:focus-visible,
.tap-root.tap-root .tap-vfilter__go:focus-visible,
.tap-chrome-header.tap-chrome-header .tap-chrome-cta:focus-visible,
.tap-home-root.tap-home-root .tap-vertical-empty__link:focus-visible{
	outline:2px solid var(--tap-primary);
	outline-offset:2px;
	box-shadow:var(--ds-focus);
}
.tap-root.tap-root .tap-btn[disabled],
.tap-root.tap-root .tap-btn[aria-disabled="true"],
.tap-root.tap-root .tap-cta[disabled],
.tap-root.tap-root .tap-sam-card-add[disabled],
.tap-root button[disabled]{
	opacity:.5;
	cursor:not-allowed;
	transform:none;
	box-shadow:none;
	/* Nothing should react to a pointer it cannot serve. */
	pointer-events:none;
}
/* A button mid-request must look busy and must not accept a second press —
   the cheapest guard there is against a double booking or double payment. */
.tap-root.tap-root .is-loading,
.tap-root [data-loading="1"]{
	pointer-events:none;
	position:relative;
	color:transparent!important;
}
.tap-root.tap-root .is-loading::after,
.tap-root [data-loading="1"]::after{
	content:"";
	position:absolute; inset-block-start:50%; inset-inline-start:50%;
	inline-size:18px; block-size:18px; margin:-9px 0 0 -9px;
	border-radius:50%;
	border:2px solid color-mix(in srgb, currentColor 30%, transparent);
	border-block-start-color:var(--tap-cta-text, #fff);
	animation:ds-spin .7s linear infinite;
}
@keyframes ds-spin{to{transform:rotate(360deg)}}

/* Phone: the primary action gets the comfortable height the brief asks for. */
@media (max-width:767.98px){
	.tap-root.tap-root .tap-btn-primary,
	.tap-root.tap-root .tap-fcard-cta,
	.tap-root.tap-root .tap-sam-card-add,
	.tap-root.tap-root .tap-cta{min-block-size:50px; font-size:15px}
}

/* ==========================================================================
   3. SURFACES — one radius and one elevation ladder for every card
   ========================================================================== */
/*
 * `!important` is deliberate and is confined to this block.
 *
 * Radius and elevation are the two properties this layer exists to own, and
 * several component sheets set them from selectors deeper than any sane
 * scoping here could out-specify — after one round of raising specificity,
 * nine of seventeen service cards still kept a 22px corner and a
 * 0 12px 32px shadow while the other eight took the token. The alternative
 * is a specificity arms race that the next component to be written wins
 * again. One documented override in the system layer is the smaller cost.
 *
 * It applies to geometry ONLY. Colour, layout and behaviour stay with the
 * components.
 */
.tap-root.tap-root .tap-fcard,
.tap-root.tap-root .tap-pcard,
.tap-root.tap-root .tap-sam-card,
.tap-home-root.tap-home-root .tap-home-trust-card,
.tap-home-root.tap-home-root .tap-home-step,
.tap-root.tap-root .tap-addon-card,
.tap-root.tap-root .tap-plan-card{
	border-radius:var(--ds-radius-lg)!important;
	box-shadow:var(--ds-shadow-2)!important;
	border:1px solid color-mix(in srgb, var(--tap-line) 72%, transparent);
	background:var(--tap-card, #fff);
}
/*
 * A button label is a label: it stays on its line and the type steps down
 * before the box grows. .tap-sam-card-add is the WRAPPER — the control it
 * holds is .tap-sam-cta, which the store styles itself and which now reads
 * the same --ds-control-h and --ds-radius-md as every other button.
 */
.tap-root.tap-root .tap-sam-cta{
	white-space:nowrap;
	font-size:clamp(13px, 2.6vw, 15px);
}
/* Desktop hover: a small, single, consistent lift. */
@media (hover:hover) and (min-width:768px){
	.tap-root.tap-root .tap-fcard:hover,
	.tap-root.tap-root .tap-pcard:hover,
	.tap-root.tap-root .tap-sam-card:hover,
	.tap-home-root.tap-home-root .tap-home-trust-card:hover{
		box-shadow:var(--ds-shadow-3);
		border-color:color-mix(in srgb, var(--tap-line) 100%, transparent);
	}
}
/* Media inside a card follows the card's corner, one step tighter. */
.tap-root.tap-root .tap-fcard-art,
.tap-root.tap-root .tap-sam-card-media{
	border-radius:calc(var(--ds-radius-lg) - 4px);
	overflow:hidden;
}
.tap-root.tap-root .tap-fcard-media,
.tap-root.tap-root .tap-sam-card img{
	inline-size:100%; block-size:100%;
	object-fit:cover;
	/* Faces and deities sit high in devotional artwork. */
	object-position:center 32%;
	display:block;
}

/* ==========================================================================
   4. TYPE — one scale for the shared roles
   ========================================================================== */
.tap-root.tap-root .tap-sec-eyebrow,
.tap-home-root.tap-home-root .tap-sec-eyebrow{
	font-family:var(--tap-font-body);
	font-size:12px;
	font-weight:800;
	/* Was 1.92px in one place and 1.2px in another. */
	letter-spacing:.14em;
	text-transform:uppercase;
	line-height:1.2;
}
.tap-root.tap-root .tap-sec-title,
.tap-home-root.tap-home-root .tap-sec-title{
	font-family:var(--tap-font-display, var(--tap-font-heading));
	font-size:clamp(24px, 3.2vw, 40px);
	font-weight:600;
	line-height:1.1;
	letter-spacing:-.025em;
	margin-block-start:6px;
}
/* Card titles are titles, not paragraphs: two lines, then an ellipsis. */
.tap-root.tap-root .tap-fcard-name,
.tap-root.tap-root .tap-sam-card-title,
.tap-home-root.tap-home-root .tap-home-trust-card h3,
.tap-home-root.tap-home-root .tap-home-why-card h3{
	font-family:var(--tap-font-body);
	font-size:15.5px;
	font-weight:700;
	line-height:1.3;
	letter-spacing:-.005em;
	display:-webkit-box;
	-webkit-line-clamp:2;
	-webkit-box-orient:vertical;
	overflow:hidden;
	text-wrap:balance;
}
.tap-root.tap-root .tap-fcard-summary,
.tap-home-root.tap-home-root .tap-home-trust-card p,
.tap-home-root.tap-home-root .tap-home-why-card p{
	font-size:13.5px;
	line-height:1.55;
	color:var(--tap-muted);
	/* Readability measure — long lines are the other way text stops working. */
	max-inline-size:62ch;
}

/* ==========================================================================
   5. ICONS — the audit found six sizes at one stroke weight. Keep the stroke,
   settle the sizes. Explicit width/height attributes on the SVG still win
   where a component genuinely needs a bespoke size.
   ========================================================================== */
.tap-root.tap-root .tap-sec-action svg,
.tap-root.tap-root .tap-vchip svg{
	inline-size:var(--ds-icon-sm); block-size:var(--ds-icon-sm);
	flex:0 0 auto;
}

/* ==========================================================================
   6. RAILS — one strong card, a deliberate peek at the next
   ========================================================================== */
@media (max-width:767.98px){
	.tap-root.tap-root .tap-rail,
	.tap-root [class*="-rail"]:not(.tap-review-rail){
		scroll-snap-type:x mandatory;
		scroll-padding-inline:var(--ds-space-4);
		-webkit-overflow-scrolling:touch;
		/* Vertical gestures belong to the page, not the rail. */
		touch-action:pan-x pan-y;
		overscroll-behavior-x:contain;
	}
	.tap-root.tap-root .tap-rail > *,
	.tap-root [class*="-rail"]:not(.tap-review-rail) > *{
		scroll-snap-align:start;
	}
}

/* ==========================================================================
   7. SKELETONS — the loading state uses the same geometry as the thing it
   stands in for, so nothing moves when the real content lands.
   ========================================================================== */
.tap-root.tap-root .tap-skeleton{
	border-radius:var(--ds-radius-lg);
	background:linear-gradient(100deg,
		color-mix(in srgb, var(--tap-ink) 5%, var(--tap-card)) 30%,
		color-mix(in srgb, var(--tap-ink) 9%, var(--tap-card)) 50%,
		color-mix(in srgb, var(--tap-ink) 5%, var(--tap-card)) 70%);
	background-size:220% 100%;
	animation:ds-shimmer 1.4s ease-in-out infinite;
}
@keyframes ds-shimmer{from{background-position:180% 0}to{background-position:-40% 0}}

/* ==========================================================================
   8. MOTION — every animation in this file is optional.
   ========================================================================== */
@media (prefers-reduced-motion: reduce){
	.tap-root.tap-root .tap-btn,
	.tap-root.tap-root .tap-cta,
	.tap-root.tap-root .tap-fcard-cta,
	.tap-root.tap-root .tap-sam-card-add,
	.tap-root.tap-root .tap-fcard,
	.tap-root.tap-root .tap-sam-card,
	.tap-chrome-header.tap-chrome-header .tap-chrome-cta{transition:none}
	.tap-root.tap-root .tap-btn:active,
	.tap-root.tap-root .tap-cta:active,
	.tap-root.tap-root .tap-fcard-cta:active{transform:none}
	.tap-root.tap-root .is-loading::after,
	.tap-root [data-loading="1"]::after,
	.tap-root.tap-root .tap-skeleton{animation:none}
}
