/* ---------------------------------------------------------------------------
   The feature pages' demos (Components::FeatureStage): short scenes drawn in
   HTML and CSS — no images, no video — the same way as the landing page's
   showcase (showcase.css), so they never go stale the way screenshots do.

   How it plays: stage_controller.js gives the stage [data-play], and every
   animation below hangs off it. Each element's resting style is its LAST
   frame and every animation fills `both` from its first, so a stage that
   isn't playing — reduced motion, no JavaScript — shows how its scene ends.

   Unlike the showcase, the timelines aren't written here one scene at a time.
   The pages place each element on the timeline themselves with a few inline
   custom properties, and these classes do the moving:

     --d     when it happens, from the start of the scene (default 0s)
     --len   how long it stays, for things that come and go (.fx-blip …)
     --x/--y where it comes from (.fx-slide) or goes to (.fx-shift)
     --i     a typed character's index (.fx-typed), --step the pace

   A hidden .fx-clock runs for the scene's length (--fx-duration, on the stage)
   and its animationend starts the scene over; [data-paused] stops it with
   everything else. What moves is transform and opacity, which the browser
   composites without laying the page out again — all but typed text, which
   widens a letter at a time.

   The drawings are laid out in px at a natural width (--fx-w): the controller
   zooms them down to fit a narrower column instead of letting them reflow.

   It all sits in Tailwind's components layer, so a utility class on a piece
   of a drawing (mt-2, whitespace-normal…) wins over the fx- class beside it.
--------------------------------------------------------------------------- */

@layer components {

.fx-stage {
  --fx-bezel: #111827;
  --fx-ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
  --fx-green: #16a34a;
  --fx-flash: color-mix(in oklab, var(--accent) 22%, transparent);
  position: relative;
}

:root.dark .fx-stage {
  --fx-bezel: #333333;
  --fx-green: #4ade80;
}

@media (prefers-color-scheme: dark) {
  :root:not(.light) .fx-stage {
    --fx-bezel: #333333;
    --fx-green: #4ade80;
  }
}

.fx-stage[data-paused] *,
.fx-stage[data-paused] *::before,
.fx-stage[data-paused] *::after {
  animation-play-state: paused !important;
}

.fx-clock {
  position: absolute;
  width: 0;
  height: 0;
}

.fx-stage[data-play] .fx-clock { animation: fx-clock var(--fx-duration) linear both; }

/* Each loop fades in from nothing and out again at the end, so starting over
   isn't a jump cut. */
.fx-stage[data-play] .fx-frame { animation: fx-cycle var(--fx-duration) linear both; }

.fx-fit {
  display: flex;
  justify-content: center;
  width: 100%;
}

.fx-frame {
  width: var(--fx-w);
  flex: none;
}

/* Without JavaScript nothing zooms the drawing to fit: shrink it on phones. */
@media (max-width: 480px) {
  .fx-frame { zoom: 0.78; }
}

/* The pause button: a small round control in the panel's corner. */
.fx-toggle {
  position: absolute;
  right: 10px;
  bottom: 10px;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 9999px;
  background: var(--canvas);
  color: var(--muted);
  opacity: 0.75;
  transition: opacity 0.2s ease, color 0.2s ease;

  &:hover { opacity: 1; color: var(--content); }
  &:focus-visible { opacity: 1; outline: 2px solid var(--accent); outline-offset: 2px; }

  svg { width: 14px; height: 14px; }
}

/* Under the hero's demo it sits centered, below the drawing. */
.fx-stage-hero .fx-toggle {
  right: auto;
  bottom: 0;
  left: 50%;
  margin-left: -15px;
  background: var(--canvas);
}

.fx-toggle-play { display: none; }
.fx-stage[data-user-paused] .fx-toggle-pause { display: none; }
.fx-stage[data-user-paused] .fx-toggle-play { display: block; }

/* --- Frames --------------------------------------------------------------- */

/* A phone, like the showcase's. */
.fx-phone {
  position: relative;
  width: 272px;
  height: 552px;
  padding: 8px;
  border-radius: 46px;
  background: var(--fx-bezel);
  box-shadow: 0 30px 60px -20px rgb(0 0 0 / 0.35);
}

.fx-screen {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  border-radius: 38px;
  background: var(--canvas);
  overflow: hidden;
  isolation: isolate;

  &::before {
    content: "";
    position: absolute;
    z-index: 20;
    top: 10px;
    left: 50%;
    width: 78px;
    height: 22px;
    margin-left: -39px;
    border-radius: 9999px;
    background: var(--fx-bezel);
  }

  > .fx-bar:first-child { padding-top: 42px; }
}

/* A piece of the app on its own: a card of the page's colour lifted off the
   panel. */
.fx-card {
  position: relative;
  border-radius: 14px;
  background: var(--canvas);
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.4);
  overflow: hidden;
  isolation: isolate;
}

/* A sheet of paper: light in either theme, the way a print-out is. */
.fx-paper {
  position: relative;
  padding: 22px 22px 26px;
  border-radius: 4px;
  background: #ffffff;
  color: #1f2937;
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.08), 0 24px 48px -24px rgb(0 0 0 / 0.45);
  overflow: hidden;

  --fx-paper-muted: #6b7280;
  --fx-paper-line: #e5e7eb;
}

/* Shared type and colour inside every drawing. */
.fx-phone,
.fx-card,
.fx-paper,
.fx-loose {
  font-size: 13px;
  line-height: 1.4;
  text-align: left;
}

.fx-phone,
.fx-card,
.fx-loose {
  color: var(--content);
}

.fx-icon { width: 15px; height: 15px; flex: none; }
.fx-muted { color: var(--muted); }
.fx-subtle { color: var(--subtle); }
.fx-accent { color: var(--accent); }
.fx-green { color: var(--fx-green); }
.fx-strong { font-weight: 600; }
.fx-small { font-size: 11.5px; }
.fx-tiny { font-size: 10.5px; }
.fx-big { font-size: 17px; font-weight: 700; line-height: 1.25; }
.fx-mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.fx-nowrap { white-space: nowrap; }
.fx-right { text-align: right; }
.fx-grow { flex: 1; min-width: 0; }
.fx-rel { position: relative; }

/* A value that just changed lights up for a moment (with .fx-flash). */
.fx-mark {
  display: inline-block;
  margin: -1px -4px;
  padding: 1px 4px;
  border-radius: 5px;
}

/* A radio button: its dot comes and goes with .fx-pop / .fx-out. */
.fx-radio {
  display: grid;
  place-items: center;
  width: 15px;
  height: 15px;
  flex: none;
  border-radius: 9999px;
  background: var(--surface-muted);

  > span {
    width: 7px;
    height: 7px;
    border-radius: 9999px;
    background: var(--accent);
  }
}

.fx-eyebrow {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--subtle);
}

.fx-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.fx-col {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.fx-between {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.fx-pad { padding: 12px 14px; }
.fx-pad-lg { padding: 16px 18px; }

/* Grid overlap: things that replace each other share one cell, so swapping
   them never moves what's around. */
.fx-slot {
  display: grid;

  > * { grid-area: 1 / 1; }
}

/* --- App pieces ----------------------------------------------------------- */

.fx-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 12px 14px 8px;
  flex: none;
}

.fx-bar-center { justify-content: center; }

.fx-search {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 34px;
  padding: 0 11px;
  border-radius: 8px;
  background: var(--surface);
  color: var(--subtle);
  white-space: nowrap;
  overflow: hidden;
}

.fx-token {
  display: inline-flex;
  align-items: center;
  padding: 1px 7px;
  border-radius: 6px;
  background: color-mix(in oklab, var(--accent) 14%, transparent);
  color: var(--content);
  font-size: 12px;
}

/* Rows of a list: panels on the page. (A row may sit in a wrapper that
   moves it, hence li and not > li.) */
.fx-list {
  display: flex;
  flex-direction: column;
  gap: 6px;

  li {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: 44px;
    padding: 6px 12px;
    border-radius: 10px;
    background: var(--surface);
    font-size: 12.5px;
    line-height: 1.3;
  }
}

/* A grid of records: a header row and rows on the page, columns set inline
   (--cols). */
.fx-table {
  font-size: 12px;

  > div {
    display: grid;
    grid-template-columns: var(--cols);
    gap: 10px;
    align-items: center;
    padding: 7px 12px;
    white-space: nowrap;

    > * { overflow: hidden; text-overflow: ellipsis; }
  }

  > div:first-child {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--subtle);
  }

  > div + div { border-top: 2px solid var(--surface); }
}

/* A record's values: label above the value. */
.fx-values {
  display: grid;
  grid-template-columns: var(--cols, 1fr 1fr);
  gap: 10px 14px;
}

.fx-label {
  display: block;
  font-size: 10.5px;
  color: var(--muted);
}

.fx-value { display: block; font-weight: 500; }

/* An input: a fill, no edge, like the app's .field. */
.fx-input {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 30px;
  padding: 5px 9px;
  border-radius: 7px;
  background: var(--surface);
  white-space: nowrap;
  overflow: hidden;
}

.fx-panel {
  border-radius: 10px;
  background: var(--surface);
}

.fx-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 9999px;
  background: var(--surface-muted);
  color: var(--content);
  font-size: 11.5px;
  white-space: nowrap;
}

.fx-chip-accent {
  background: color-mix(in oklab, var(--accent) 16%, transparent);
  color: var(--accent);
}

.fx-chip-green {
  background: color-mix(in oklab, var(--fx-green) 16%, transparent);
  color: var(--fx-green);
}

.fx-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 30px;
  padding: 0 12px;
  border-radius: 8px;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
}

.fx-btn-quiet {
  background: var(--surface);
  color: var(--content);
}

.fx-avatar {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  flex: none;
  border-radius: 9999px;
  background: var(--inverse);
  color: var(--on-inverse);
  font-size: 10.5px;
  font-weight: 600;
}

.fx-avatar-ai {
  background: var(--accent);
  color: #ffffff;
}

.fx-box {
  display: grid;
  place-items: center;
  width: 15px;
  height: 15px;
  flex: none;
  border-radius: 4px;
  background: var(--surface-muted);
  color: #ffffff;

  .fx-icon { width: 11px; height: 11px; opacity: 0; }
}

.fx-box-on {
  background: var(--accent);

  .fx-icon { opacity: 1; }
}

/* A field's kind, as the field list shows it. */
.fx-kind {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 7px 1px 5px;
  border-radius: 6px;
  background: var(--surface-muted);
  color: var(--muted);
  font-size: 11px;
  white-space: nowrap;

  .fx-icon { width: 12px; height: 12px; }
}

/* Controls a finger taps: the tap is drawn inside them. */
.fx-btn,
.fx-input,
.fx-chip,
.fx-kind,
.fx-lenses > span { position: relative; }

/* --- Chat ----------------------------------------------------------------- */

.fx-thread {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  padding: 6px 14px;
}

.fx-bubble {
  max-width: 84%;
  padding: 7px 11px;
  border-radius: 16px;
}

.fx-mine {
  align-self: flex-end;
  background: var(--surface);
  border-bottom-right-radius: 5px;
}

.fx-theirs {
  background: var(--surface);
  border-bottom-left-radius: 5px;
}

.fx-tool {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: 6px;
  padding: 3px 10px 3px 6px;
  border-radius: 9999px;
  background: var(--surface);
  color: var(--muted);
  font-size: 11.5px;
}

.fx-tool-icon {
  position: relative;
  width: 14px;
  height: 14px;
  flex: none;

  > .fx-icon {
    position: absolute;
    inset: 0;
    width: 14px;
    height: 14px;
    color: var(--fx-green);
  }
}

.fx-spinner {
  position: absolute;
  inset: 1px;
  border: 2px solid var(--surface-muted);
  border-top-color: var(--muted);
  border-radius: 9999px;
  opacity: 0;
}

.fx-dots {
  display: inline-flex;
  gap: 4px;
  padding: 9px 2px;
  opacity: 0;

  > span {
    width: 6px;
    height: 6px;
    border-radius: 9999px;
    background: var(--subtle);
  }
}

.fx-composer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: auto 12px 16px;
  height: 38px;
  padding: 0 12px;
  border-radius: 9999px;
  background: var(--surface);
  color: var(--subtle);
  flex: none;
}

/* --- Things that happen --------------------------------------------------- */

/* A finger's tap: no backwards fill (`forwards`, not `both`), so it isn't
   sitting there before it happens. Placed with inline top/left. */
.fx-tap {
  position: absolute;
  z-index: 10;
  width: 40px;
  height: 40px;
  margin: -20px 0 0 -20px;
  border-radius: 9999px;
  background: var(--content);
  opacity: 0;
  pointer-events: none;
}

.fx-caret {
  display: inline-block;
  width: 1.5px;
  height: 1.1em;
  margin-left: 1px;
  vertical-align: text-bottom;
  opacity: 0;

  &::before {
    content: "";
    display: block;
    height: 100%;
    background: var(--accent);
  }
}

.fx-typed .fx-char {
  display: inline-block;
  max-width: 1em;
  overflow: hidden;
  vertical-align: bottom;
  white-space: pre;
}

.fx-word {
  display: inline-block;
  white-space: nowrap;
  vertical-align: bottom;
}

/* Text that's been corrected: struck through, the line drawn on cue. */
.fx-struck {
  position: relative;
  color: var(--subtle);

  &::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 55%;
    height: 1.5px;
    background: currentColor;
    transform-origin: left;
  }
}

.fx-out,
.fx-blip,
.fx-away { opacity: 0; }
.fx-shift { transform: translateY(var(--y, 0)); }

.fx-stage[data-play] {
  .fx-in { animation: fx-in 0.38s var(--fx-ease-out) var(--d, 0s) both; }
  .fx-fade { animation: fx-fade 0.4s ease var(--d, 0s) both; }
  .fx-out { animation: fx-out 0.3s ease var(--d, 0s) both; }
  .fx-blip { animation: fx-blip var(--len, 1s) linear var(--d, 0s) both; }
  .fx-pop { animation: fx-pop 0.32s var(--fx-ease-out) var(--d, 0s) both; }
  .fx-drop { animation: fx-drop 0.38s var(--fx-ease-out) var(--d, 0s) both; }
  .fx-rise { animation: fx-rise 0.5s var(--fx-ease-out) var(--d, 0s) both; }
  .fx-grow-y { transform-origin: bottom; animation: fx-grow-y 0.5s var(--fx-ease-out) var(--d, 0s) both; }
  .fx-grow-x { transform-origin: left; animation: fx-grow-x var(--dur, 0.6s) var(--fx-ease-out) var(--d, 0s) both; }
  .fx-slide { animation: fx-slide 0.5s var(--fx-ease-out) var(--d, 0s) both; }
  .fx-away { animation: fx-away 0.45s cubic-bezier(0.4, 0, 0.2, 1) var(--d, 0s) both; }
  .fx-shift { animation: fx-shift 0.45s var(--fx-ease-out) var(--d, 0s) both; }
  .fx-flash { animation: fx-flash 1.4s ease-out var(--d, 0s) both; }
  .fx-press { animation: fx-press 0.25s ease var(--d, 0s) both; }
  .fx-tap { animation: fx-tap 0.5s ease-out var(--d, 0s) forwards; }
  .fx-struck::after { animation: fx-grow-x 0.35s ease var(--d, 0s) both; }
  .fx-typed .fx-char { animation: fx-char 0.01s step-end calc(var(--d, 0s) + var(--i) * var(--step, 0.055s)) both; }
  .fx-caret { animation: fx-blip var(--len, 1s) linear var(--d, 0s) both; }
  .fx-caret::before { animation: fx-blink 0.9s step-end infinite; }
  .fx-dots { animation: fx-blip var(--len, 1s) linear var(--d, 0s) both; }
  .fx-dots > span { animation: fx-dot 0.9s ease-in-out infinite; }
  .fx-dots > span:nth-child(2) { animation-delay: 0.15s; }
  .fx-dots > span:nth-child(3) { animation-delay: 0.3s; }
  .fx-spinner { animation: fx-blip var(--len, 1s) linear var(--d, 0s) both, fx-spin 0.7s linear infinite; }
  .fx-box-on { animation: fx-box 0.25s ease var(--d, 0s) both; }
  .fx-box-on .fx-icon { animation: fx-pop 0.25s var(--fx-ease-out) var(--d, 0s) both; }
}

/* Pieces that only some scenes need. */

/* A document being read: a line of light sweeps down it. */
.fx-scan {
  position: absolute;
  inset: 0 0 auto;
  height: 2px;
  background: #22c55e;
  box-shadow: 0 0 12px 3px rgb(34 197 94 / 0.55);
  opacity: 0;
}

.fx-stage[data-play] .fx-scan { animation: fx-scan var(--len, 1.2s) ease-in-out var(--d, 0s) both; }

/* A camera's viewfinder over the screen, gone once the photo's taken. */
.fx-viewfinder {
  position: absolute;
  z-index: 5;
  inset: 0;
  display: grid;
  place-items: center;
  background: #0c0c0c;
}

.fx-shutter {
  position: absolute;
  bottom: 28px;
  left: 50%;
  width: 52px;
  height: 52px;
  margin-left: -26px;
  border-radius: 9999px;
  background: #ffffff;
  box-shadow: 0 0 0 4px #0c0c0c, 0 0 0 6px #ffffff;
}

.fx-whiteout {
  position: absolute;
  z-index: 6;
  inset: 0;
  background: #ffffff;
  opacity: 0;
  pointer-events: none;
}

.fx-stage[data-play] .fx-whiteout { animation: fx-whiteout 0.4s ease-out var(--d, 0s) both; }

/* A bottom sheet and the dimming behind it. */
.fx-scrim {
  position: absolute;
  z-index: 7;
  inset: 0;
  background: rgb(0 0 0 / 0.25);
}

.fx-sheet {
  position: absolute;
  z-index: 8;
  inset: auto 0 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 16px 24px;
  border-radius: 20px 20px 0 0;
  background: var(--surface);
  box-shadow: 0 -10px 30px -10px rgb(0 0 0 / 0.25);
}

.fx-stage[data-play] .fx-sheet { animation: fx-sheet 0.45s var(--fx-ease-out) var(--d, 0s) both; }

/* A small receipt or invoice, drawn on paper. */
.fx-doc {
  position: relative;
  padding: 12px 12px 14px;
  border-radius: 5px;
  background: #fbfaf5;
  color: #262626;
  font: 9.5px/14px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  box-shadow: 0 6px 20px -8px rgb(0 0 0 / 0.45);
  overflow: hidden;

  .fx-doc-head {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    line-height: 16px;
  }

  .fx-doc-rule {
    margin: 5px 0;
    border-top: 1px dashed #a3a3a3;
  }

  .fx-between { gap: 6px; white-space: nowrap; }
}

/* An email, as a mail app lists it. */
.fx-mail {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--surface);
}

.fx-attachment {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  align-self: flex-start;
  padding: 4px 9px 4px 6px;
  border-radius: 8px;
  background: var(--canvas);
  font-size: 11.5px;
}

.fx-file-badge {
  display: grid;
  place-items: center;
  width: 20px;
  height: 22px;
  border-radius: 3px;
  background: #dc2626;
  color: #ffffff;
  font-size: 7px;
  font-weight: 700;
}

/* Code, for the API. */
.fx-code {
  padding: 12px 14px;
  border-radius: 10px;
  background: var(--surface);
  font: 11px/17px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  white-space: pre;
  overflow: hidden;
}

.fx-code-key { color: var(--accent); }
.fx-code-str { color: var(--fx-green); }

/* A small calendar month. */
.fx-month {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 3px;
  font-size: 9.5px;

  > span {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-height: 34px;
    padding: 3px;
    border-radius: 5px;
    background: var(--surface);
    color: var(--subtle);
  }

  i {
    display: block;
    padding: 1px 3px;
    border-radius: 3px;
    background: color-mix(in oklab, var(--accent) 18%, transparent);
    color: var(--content);
    font-style: normal;
    white-space: nowrap;
    overflow: hidden;
  }
}

/* A gallery of cards, each a photo-like block on top. */
.fx-gallery {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;

  > span {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 6px;
    border-radius: 9px;
    background: var(--surface);
    font-size: 11px;
  }

  b {
    display: block;
    height: 46px;
    border-radius: 6px;
  }
}

/* A map: land, water, streets and pins, all gradients. */
.fx-map {
  position: relative;
  height: 158px;
  border-radius: 10px;
  overflow: hidden;
  background:
    linear-gradient(115deg, transparent 0 62%, color-mix(in oklab, #60a5fa 30%, var(--surface)) 62% 100%),
    linear-gradient(0deg, transparent 0 47%, var(--canvas) 47% 51%, transparent 51%),
    linear-gradient(90deg, transparent 0 34%, var(--canvas) 34% 37%, transparent 37%),
    linear-gradient(28deg, transparent 0 58%, var(--canvas) 58% 60%, transparent 60%),
    var(--surface);
}

.fx-pin {
  position: absolute;
  width: 16px;
  height: 16px;
  margin: -16px 0 0 -8px;
  border-radius: 50% 50% 50% 0;
  background: var(--accent);
  transform: rotate(-45deg);
  box-shadow: 0 2px 6px rgb(0 0 0 / 0.3);

  &::after {
    content: "";
    position: absolute;
    inset: 5px;
    border-radius: 9999px;
    background: #ffffff;
  }
}

/* The view switcher's icons, the active one underlined. */
.fx-lenses {
  display: flex;
  gap: 4px;

  > span {
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    border-radius: 7px;
    color: var(--muted);
  }
}

.fx-underline {
  position: absolute;
  bottom: -2px;
  left: 0;
  width: 26px;
  height: 2px;
  border-radius: 2px;
  background: var(--content);
}

/* A short confirmation floating over the bottom of a screen. */
.fx-toast {
  position: absolute;
  z-index: 9;
  left: 50%;
  bottom: var(--bottom, 18px);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  translate: -50% 0;
  padding: 6px 12px;
  border-radius: 9999px;
  background: var(--inverse);
  color: var(--on-inverse);
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
  box-shadow: 0 8px 20px -8px rgb(0 0 0 / 0.4);

  .fx-icon { width: 13px; height: 13px; }
}

/* A dropdown or popover, lifted off what's under it. */
.fx-menu {
  position: absolute;
  z-index: 8;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 5px;
  border-radius: 10px;
  background: var(--canvas);
  box-shadow: 0 0 0 1px var(--surface-muted), 0 14px 30px -10px rgb(0 0 0 / 0.35);
  font-size: 12px;

  > * {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 5px 8px;
    border-radius: 6px;
    white-space: nowrap;
  }
}

/* A segmented control; the picked segment is a lighter fill, moved by
   fading one .fx-seg-on out and another in. */
.fx-seg {
  display: flex;
  gap: 2px;
  padding: 2px;
  border-radius: 8px;
  background: var(--surface-muted);
  font-size: 11px;

  > span {
    position: relative;
    flex: 1;
    display: grid;
    place-items: center;
    height: 22px;
    padding: 0 4px;
    white-space: nowrap;
    isolation: isolate;
  }

  .fx-icon { width: 13px; height: 13px; }
}

.fx-seg-on {
  position: absolute;
  z-index: -1;
  inset: 0;
  border-radius: 6px;
  background: var(--canvas);
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.15);
}

/* A selected piece of a layout, outlined. */
.fx-selected {
  box-shadow: 0 0 0 2px var(--accent);
  border-radius: 4px;
}

/* A line of text still to come, as a grey bar (on paper). */
.fx-skel {
  display: block;
  height: 6px;
  border-radius: 3px;
  background: #e5e7eb;
}

.fx-skel-dark { background: #9ca3af; }

/* A progress bar; its fill grows with .fx-grow-x over --dur. */
.fx-progress {
  height: 5px;
  border-radius: 9999px;
  background: var(--surface-muted);
  overflow: hidden;

  > span {
    display: block;
    height: 100%;
    background: var(--accent);
  }
}

/* A tile in a grid: a field kind, an account. */
.fx-tile {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 8px 10px;
  border-radius: 10px;
  background: var(--surface);
  font-size: 12px;
  line-height: 1.3;
}

/* A list whose rows move and go: rows are placed absolutely (--top) inside a
   box as tall as the list. */
.fx-stack {
  position: relative;

  > * {
    position: absolute;
    left: 0;
    right: 0;
    top: var(--top, 0);
  }
}

/* --- Keyframes ------------------------------------------------------------ */

@keyframes fx-clock { from { opacity: 0; } to { opacity: 0; } }
@keyframes fx-cycle { 0% { opacity: 0; } 3%, 97% { opacity: 1; } 100% { opacity: 0; } }
@keyframes fx-in { from { opacity: 0; transform: translateY(6px) scale(0.98); } to { opacity: 1; transform: none; } }
@keyframes fx-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes fx-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes fx-blip { 0% { opacity: 0; } 8%, 92% { opacity: 1; } 100% { opacity: 0; } }
@keyframes fx-pop { from { opacity: 0; transform: scale(0.4); } to { opacity: 1; transform: none; } }
@keyframes fx-drop { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: none; } }
@keyframes fx-rise { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }
@keyframes fx-grow-y { from { transform: scaleY(0); } to { transform: none; } }
@keyframes fx-grow-x { from { transform: scaleX(0); } to { transform: none; } }
@keyframes fx-slide { from { transform: translate(var(--x, 0), var(--y, 0)); } to { transform: none; } }
@keyframes fx-away { from { opacity: 1; transform: none; } to { opacity: 0; transform: translate(var(--x, 0), var(--y, 0)); } }
@keyframes fx-shift { from { transform: translateY(var(--from, 0)); } to { transform: translateY(var(--y, 0)); } }
@keyframes fx-flash { 0% { box-shadow: inset 0 0 0 999px transparent; } 12% { box-shadow: inset 0 0 0 999px var(--fx-flash); } 100% { box-shadow: inset 0 0 0 999px transparent; } }
@keyframes fx-press { 50% { transform: scale(0.93); } }
@keyframes fx-tap { from { opacity: 0.25; transform: scale(0.3); } to { opacity: 0; transform: scale(1.4); } }
@keyframes fx-char { from { max-width: 0; } to { max-width: 1em; } }
@keyframes fx-blink { 0% { opacity: 1; } 50% { opacity: 0; } }
@keyframes fx-dot { 0%, 100% { transform: translateY(0); opacity: 0.5; } 50% { transform: translateY(-3px); opacity: 1; } }
@keyframes fx-spin { to { rotate: 360deg; } }
@keyframes fx-box { from { background-color: var(--surface-muted); } to { background-color: var(--accent); } }
@keyframes fx-scan { 0% { transform: translateY(0); opacity: 0; } 12%, 88% { opacity: 1; } 100% { transform: translateY(var(--y, 180px)); opacity: 0; } }
@keyframes fx-whiteout { 0% { opacity: 0; } 25% { opacity: 0.85; } 100% { opacity: 0; } }
@keyframes fx-sheet { from { transform: translateY(110%); } to { transform: none; } }

/* Reduced motion: nothing moves. Each stage shows its scene's last frame, and
   there's nothing to pause. */
@media (prefers-reduced-motion: reduce) {
  .fx-stage *,
  .fx-stage *::before,
  .fx-stage *::after {
    animation: none !important;
    transition: none !important;
  }

  .fx-stage .fx-toggle { display: none; }
}

} /* @layer components */
