/* Adds scrolling to an element where the elements fade as they are scrolled out of view */
.scroll-fade {
  overflow-y: auto;

  -webkit-mask-image: linear-gradient(
    to bottom,
    transparent 0%,
    black 10%,
    black 90%,
    transparent 100%
  );
  mask-image: linear-gradient(
    to bottom,
    transparent 0%,
    black 10%,
    black 90%,
    transparent 100%
  );
}

/* ---- AI surfaces --------------------------------------------------------
   These deliberately do NOT follow the palette. Ledger muted --tblr-purple to
   #6B4E8F and --tblr-cyan to #2A6E82 -- correct for a category tag on a report,
   but it turned the AI gradient into mud. The AI affordance is the one place in
   the product allowed to be vivid: it marks generated content, which has to be
   distinguishable from figures the system stands behind.

   So the pre-Ledger pair is pinned here as its own tokens rather than repeated
   as a literal in four gradients. Change them here, not in Globals. */
:root {
  --lens-ai-purple: #ae3ec9;
  --lens-ai-cyan: #17a2b8;
  --lens-ai-sweep: linear-gradient(
    135deg,
    var(--lens-ai-purple),
    var(--lens-ai-cyan),
    var(--lens-ai-purple)
  );
}

.fg-ai {
  background: var(--lens-ai-sweep);
  background-clip: text;
	background-size: cover;
	background-position: center;
  color: transparent;
}

.border-ai {
  position: relative;
  border: 0;
}

.border-ai::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: var(--lens-ai-rule-width) var(--lens-ai-border-width) var(--lens-ai-border-width);
  background: var(--lens-ai-sweep);
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  -webkit-mask-composite: xor;
  pointer-events: none;
}

.ai {
  background: var(--lens-ai-sweep);
  background-size: 200% 200%;
  background-position: 0% 0%;
  color: #fff;
  transition: background-position 0.4s ease;
}

.ai:hover {
  background: var(--lens-ai-sweep);
  background-position: 100% 100%;
  background-size: 200% 200%;
  color: #fff;
  transition: background-position 0.4s ease;
}

/* Marks the admin interface as somewhere other than the product proper.
   Diagonal hatching rather than dots: it sits better against a design made of
   straight rules, and a 1-in-10 duty cycle keeps it quiet enough to read
   tables over. The stripe is transparent-gapped so the surface underneath
   still supplies the colour, which is what makes it work on both the body and
   a card. */
.hatched {
  background-color: var(--tblr-body-bg);
  background-image: repeating-linear-gradient(
    45deg,
    var(--tblr-gray-100) 0 1px,
    transparent 1px 10px
  );
}

/* I need a subtext */
.subtext {
  font-size: 0.8em;
  color: var(--tblr-secondary);
}

.loadable {
	position: relative;
  padding: 0.25em !important;
}

.loadable.loading::before {
	content: "Loading...";
	position: absolute;
	inset: 0;
	z-index: 10;
	color: var(--tblr-dark);
	display: flex;
	align-items: center;
  backdrop-filter: blur(2px);
	justify-content: center;
	padding-top: 1rem; /* leaves room above the text for the spinner */
}

.loadable.loading::after {
	content: "";
	position: absolute;
	top: calc(50% - 3rem);
	left: calc(50% - 1rem);
	width: 2rem;
	height: 2rem;
	border: 0.25em solid var(--tblr-dark);
	border-right-color: transparent;
	border-radius: 50%;
	z-index: 11;
	animation: spin 0.75s linear infinite;
}

@keyframes spin {
	to { transform: rotate(360deg); }
}