/**
 * Primitive — Button
 *
 * Expected HTML:
 *   <button class="ec-button ec-button--primary ec-button--md" data-material="water">Label</button>
 *   <a class="ec-button ec-button--secondary ec-button--md" data-material="water">Label</a>
 *
 * A Fire primary button additionally needs data-ec-component="button"
 * for button.js to generate its heat field (see .ec-button__canvas and
 * .ec-button__glass below) — without it the button still renders
 * correctly, just without the internal light sources. Never authored
 * directly: button.js inserts both elements at runtime, the same
 * pattern ProgressBar's simulation canvas established (progress-bar.css).
 *
 * Optional data-ec-fire-intensity="subtle" scales the whole heat field
 * down (fewer sources, lower alpha) for a button that should read as
 * mostly glass with only a hint of warmth behind it — used by the
 * Homepage hero's CTA, where the full treatment competes too much with
 * "trust first" (EC-DESIGN.md, Core Philosophy). Competition CTAs
 * (Competition Page, Competition Card) keep the full treatment.
 *
 * Axes (EC-DESIGN-SYSTEM.md, Primitives):
 *   - Intent:   ec-button--primary | ec-button--secondary | ec-button--tertiary | ec-button--destructive
 *   - Size:     ec-button--sm | ec-button--md (default) | ec-button--lg
 *   - Material: data-material="water" | "fire" | "neutral" on the element itself.
 *               No attribute present resolves to the neutral material
 *               (materials.css default) — this file never references
 *               water or fire directly, only the generic --ec-material-*
 *               alias layer. Usage convention, not enforced here: water
 *               for ordinary buttons, fire reserved for major/celebratory
 *               calls to action only (EC-DESIGN.md, Fire — "used sparingly").
 *   - State:    :hover, :focus-visible, :active, [disabled], ec-button--loading
 *
 * Destructive is a semantic action, not a material — it always uses the
 * danger token, regardless of any data-material present.
 */

:root {
	--ec-button-height-sm: 2.25rem; /* 36px */
	--ec-button-height-md: 2.75rem; /* 44px — minimum touch target */
	--ec-button-height-lg: 3.25rem; /* 52px */

	/* Fire's heat-field colour stops (tenth pass, motion-philosophy.md;
	   read by button.js via getComputedStyle to interpolate a heat
	   source's colour from its own simulated temperature every frame —
	   colour still lives here, only its per-frame interpolation happens
	   in JS) — deep ember red through orange and amber to a rare hotter
	   yellow, deliberately independent of the shared --ec-material-fire-*
	   scale so several distinct hues exist at once, not one tint at
	   varying brightness. */
	--ec-button-ember-red: #e0432a;
	--ec-button-ember-orange: #ff7f2a;
	--ec-button-ember-amber: #ffab3d;
	--ec-button-ember-yellow: #ffd873;
}

.ec-button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--ec-space-2);
	border: 1px solid transparent;
	border-radius: var(--ec-radius-md);
	font-family: var(--ec-font-family-base);
	font-weight: var(--ec-font-weight-semibold);
	font-size: var(--ec-font-size-body);
	line-height: var(--ec-line-height-tight);
	cursor: pointer;
	user-select: none;
	text-decoration: none;
	white-space: nowrap;
	transition:
		background-color var(--ec-material-duration) var(--ec-material-ease),
		border-color var(--ec-material-duration) var(--ec-material-ease),
		box-shadow var(--ec-material-duration) var(--ec-material-ease),
		transform var(--ec-material-duration) var(--ec-material-ease);
}

/* Sizes */
.ec-button--sm {
	min-height: var(--ec-button-height-sm);
	padding: var(--ec-space-2) var(--ec-space-3);
	font-size: var(--ec-font-size-body-sm);
}

.ec-button--md {
	min-height: var(--ec-button-height-md);
	padding: var(--ec-space-3) var(--ec-space-4);
}

.ec-button--lg {
	min-height: var(--ec-button-height-lg);
	padding: var(--ec-space-4) var(--ec-space-5);
	font-size: var(--ec-font-size-body-lg);
}

/* Intent: primary — carries the active material.
   Sixth pass: identity now comes from structure, not colour or glow —
   ::before is no longer one universal highlight, it's a different
   physical technique per material, a narrow, deliberate exception to
   "components only ever reference the generic alias layer" (see this
   file's header comment and EC-DESIGN-SYSTEM.md, Materials). Tenth
   pass (motion-philosophy.md): Fire's base surface is now its own
   flat, deep colour (--ec-color-fire-700, not the shared
   --ec-material-gradient wash) rather than the mid-toned gradient
   every other Fire surface uses — a further extension of that same
   exception. This is deliberate: "roaring fire behind thick frosted
   glass" needs a dark-enough base for the embers (below) to read as
   distinct hot spots against it; a bright, gradient-lit surface has
   nothing for internal light to contrast against. overflow: hidden
   contains both materials' effects — the blur filters especially,
   which would otherwise bleed past the button's edge. */
.ec-button--primary {
	position: relative;
	background-color: var(--ec-material-color);
	background-image: var(--ec-material-gradient);
	color: var(--ec-color-neutral-0);
	box-shadow: var(--ec-material-glow), var(--ec-material-elevation);
	overflow: hidden;
}

.ec-button--primary[data-material='fire'] {
	background-color: var(--ec-color-fire-700);
	background-image: none;
}

.ec-button--primary::before {
	content: '';
	position: absolute;
	pointer-events: none;
}

/* Water: a crisp, hard-edged refraction band — light bending sharply
   through a clear surface, not a soft highlight. */
.ec-button--primary[data-material='water']::before {
	inset: 0;
	background-image: linear-gradient(
		115deg,
		transparent 0%,
		transparent 42%,
		rgba(255, 255, 255, 0.45) 43%,
		rgba(255, 255, 255, 0.45) 46%,
		transparent 47%,
		transparent 100%
	);
}

/* Fire: a simulated heat field, not decoration drawn on the surface.
   Eleventh pass (motion-philosophy.md, "material simulation, not
   decorative animation") replaces the tenth pass's DOM ember elements
   — which animated along a fixed, authored path, fed back as
   "coloured blobs on top of the button" — with a real per-frame
   simulation on .ec-button__canvas (button.js): several heat sources
   with their own drifting position and breathing temperature, each
   one's colour computed from that temperature every frame rather than
   picked once. Both elements are inserted as the button's first two
   children so they paint behind the label text.

   .ec-button__glass is the actual frosted-glass layer the brief
   describes — a real backdrop-filter: blur(), not a blurred gradient
   standing in for one — sitting between the canvas and the text. Its
   own warm, substantially opaque tint is what keeps "the orange
   frosted surface as the dominant visual layer" true regardless of
   what the heat field beneath it is doing; the simulation is meant to
   be glimpsed through it, not seen directly.

   Twelfth pass (fidelity): the glass had drifted toward reading as
   "tinted glass with coloured lights behind it" rather than "frosted
   glass with warmth behind it" — lightened toward the lighter, more
   premium orange used in earlier passes (fire-300, not fire-500) and
   made noticeably more opaque (0.55 → 0.78) so it's unambiguously the
   dominant surface again, with a slightly heavier blur (7px → 9px) —
   thicker glass, more diffusion. The heat field's own alpha was
   reduced in button.js at the same time, so the correction comes from
   both directions, not just a heavier layer stacked on an unchanged
   simulation.

   Seventeenth pass: fed back as "correct but ~20-25% too restrained,"
   with brightness, speed and particle count all explicitly ruled out
   as the fix — "increase the apparent transmission through the
   frosted glass" instead. Colour and opacity are untouched (0.78
   stands); the lever is the glass's own blur, brought back down
   (9px → 5px) so more of button.js's already-diffused heat field
   (still blurred at the canvas level first — see button.js — so this
   doesn't reopen "reads as objects") actually shows through rather
   than being smoothed away a second time by the glass on top of it.

   Eighteenth pass — art direction, explicitly licensed to overshoot:
   fed back that "almost none of it is visible" even after the
   seventeenth pass's reduction — that pass moved the right lever but
   not nearly far enough. Blur cut again, much harder this time
   (5px → 2px, near the floor of still reading as frosted rather than
   clear), and two more transmission levers added on top rather than
   touching the same one twice: saturate() raised so warm colour that
   does get through reads as more vivid, and a new contrast() so
   warmer and cooler regions read as more visibly different from each
   other. All three affect only how much of the still-unchanged heat
   field (button.js, untouched again this pass) makes it through the
   glass, not how bright, fast, or numerous the heat sources
   themselves are — colour and opacity (0.78) remain exactly as they
   were. */
.ec-button__canvas {
	position: absolute;
	inset: 0;
	pointer-events: none;
}

.ec-button__glass {
	position: absolute;
	inset: 0;
	background-color: rgba(247, 172, 112, 0.78);
	backdrop-filter: blur(2px) saturate(1.85) contrast(1.15);
	-webkit-backdrop-filter: blur(2px) saturate(1.85) contrast(1.15);
	pointer-events: none;
}

/* Plain in-flow content (the button's own text) paints before
   positioned descendants regardless of DOM order (CSS2.1 Appendix E)
   — without this, .ec-button__canvas and .ec-button__glass above
   would render on top of the label even though button.js appends them
   first. position: relative is enough to move the label into the
   "positioned, z-index: auto" paint category, where DOM order (it's
   appended last) correctly puts it above both. display: inline-flex +
   gap preserves icon+label spacing for any future Fire button that
   isn't plain text, the same as .ec-button's own layout. */
.ec-button__label {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: var(--ec-space-2);
}

/* Fourteenth pass: one step heavier than .ec-button's own semibold —
   weight only, font-size is untouched — for full-treatment Fire
   buttons specifically, where the label sits over a moving (if very
   subtle) heat field rather than a flat surface. Excludes the
   subtle/Homepage-hero variant, which stays exactly as it was. */
.ec-button--primary[data-material='fire']:not([data-ec-fire-intensity='subtle']) {
	font-weight: var(--ec-font-weight-bold);
}

.ec-button--primary:hover:not([disabled]) {
	box-shadow: var(--ec-material-glow), var(--ec-material-elevation);
	transform: scale(var(--ec-material-hover-scale));
}

/* Water's primary CTA slowly shimmers at rest — restrained motion is
   part of what tells the materials apart, not just their structure.
   Fire's equivalent "motion" is the canvas simulation above, which
   isn't a CSS animation and so isn't listed in this media query —
   button.js checks prefers-reduced-motion itself and simply doesn't
   start the simulation loop, drawing one static frame instead. */
.ec-button--primary[data-material='water'] {
	background-size: 200% 200%;
	animation: ec-water-flow var(--ec-water-flow-duration) var(--ec-ease-water) infinite;
}

/* Fire's label sits on top of the canvas and the frosted glass; this
   is a safety margin, not the primary legibility mechanism — the
   glass layer's own opacity is what actually keeps the heat field from
   competing with the text. "If the fire obscures the text the
   layering is incorrect" — this exists so a smaller margin of error
   doesn't become a real one. */
.ec-button--primary[data-material='fire'] {
	text-shadow: 0 1px 3px rgba(40, 10, 0, 0.45);
}

@media (prefers-reduced-motion: reduce) {
	.ec-button--primary[data-material='water'] {
		animation: none;
	}
}

/* Intent: secondary — material-tinted outline, not filled */
.ec-button--secondary {
	background-color: transparent;
	border-color: var(--ec-material-color);
	color: var(--ec-material-color);
}

.ec-button--secondary:hover:not([disabled]) {
	background-color: var(--ec-material-surface);
}

/* Intent: tertiary — text only, no container */
.ec-button--tertiary {
	background-color: transparent;
	border-color: transparent;
	color: var(--ec-material-color);
	padding-left: var(--ec-space-2);
	padding-right: var(--ec-space-2);
}

.ec-button--tertiary:hover:not([disabled]) {
	text-decoration: underline;
}

/* Intent: destructive — always the danger token, never a material */
.ec-button--destructive {
	background-color: var(--ec-color-danger);
	color: var(--ec-color-neutral-0);
}

.ec-button--destructive:hover:not([disabled]) {
	filter: brightness(0.92);
}

/* State */
.ec-button:focus-visible {
	outline: 2px solid var(--ec-material-color);
	outline-offset: 2px;
}

.ec-button[disabled] {
	cursor: not-allowed;
	opacity: 0.5;
	box-shadow: none;
	transform: none;
}

.ec-button--loading {
	cursor: progress;
	pointer-events: none;
	opacity: 0.75;
}

/* Intent: accent (Frontend Stage 1, 2026-10-01) — the customer site's
   solid energy-cyan action for important non-transactional steps (Log
   in, navigation CTAs). Additive: no existing intent, and nothing about
   the locked Fire/Water primary buttons above, is touched. Hierarchy:
   Fire primary remains the transactional commitment CTA (Enter Now,
   checkout); accent sits beside it for "go somewhere"; secondary
   (outline) and tertiary (text) below. No material — a flat, crisp
   fill with emitted light (glow) only on hover/focus, never at rest. */
.ec-button--accent {
	background-color: var(--ec-color-accent, var(--ec-color-water-500));
	color: var(--ec-color-text-on-accent, var(--ec-color-neutral-900));
	font-weight: var(--ec-font-weight-bold);
}

.ec-button--accent:hover:not([disabled]) {
	background-color: var(--ec-color-accent-strong, var(--ec-color-water-300));
	box-shadow: var(--ec-glow-accent-md, none);
}

.ec-button--accent:active:not([disabled]) {
	transform: translateY(1px);
}

.ec-site .ec-button--accent:focus-visible {
	outline: none;
	box-shadow: var(--ec-focus-ring);
}

/* Water primary text contrast (DNA review checkpoint, 2026-10-01).
   White on Water's pale gradient (water-100 → water-300) measured
   1.1–1.6:1 — a WCAG failure on every background. Deep navy measures
   11.5–17:1. Colour only; the material's surface, motion and glow are
   unchanged. (The Competition Card's old "+10" exclusion went with that
   button, removed in the card checkpoint.) */
.ec-button--primary[data-material='water'] {
	color: var(--ec-color-neutral-900);
}
