/* =======================================================================
   Automate — Speed animation. Self-contained, scoped stylesheet.

   This is the SOURCE stylesheet for the Automate_Speed animation. The same
   CSS is also inlined inside Automate_Speed.js (as the AutomateSpeed_CSS
   constant) so the bundle deploys as a single file and injects its own
   styles into a shadow root. If you edit this file, paste the new content
   into Automate_Speed.js between the AutomateSpeed_CSS backticks so the two
   stay in sync.

   Every selector is namespaced under `.sift-auto-speed`. The bundle's JS
   mounts a <div class="sift-auto-speed demo-stage">…</div> root, so nothing
   here can leak out and nothing in the host page can override widget
   internals unless it ALSO scopes under `.sift-auto-speed`.

   The host page needs to:
     1. Provide an element with id="auto-speed-root" for React to mount into.
     2. Load React 18 + ReactDOM 18 BEFORE Automate_Speed.js.
     3. Load IBM Plex Sans + IBM Plex Mono (imported below via Google Fonts).

   No other dependencies. No shared CSS. No other animation files referenced.
   ======================================================================= */

:host {
  all: initial;
  display: block;
  width: 100%;
  contain: content;
  font-family: "IBM Plex Sans", system-ui, sans-serif;
  font-size: 16px;
  line-height: normal;
  font-weight: 400;
  color: #EEEFEC;
  text-align: left;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
:host([hidden]) { display: none; }

@import url("https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap");

.sift-auto-speed {
  /* Brand */
  --sift-orange:        #F04A01;
  --rubber-black:       #1B1D1F;
  --steel:              #726E6E;
  --ceramic:            #EEEFEC;
  --lunar:              #848582;

  /* Gray scale */
  --gray-100: #111111;
  --gray-90:  #222222;
  --gray-80:  #353534;
  --gray-70:  #4B4C4A;
  --gray-60:  #6A6B68;
  --gray-50:  #848582;
  --gray-40:  #9E9F9C;
  --gray-30:  #BABAB6;
  --gray-20:  #D4D4D0;
  --gray-10:  #EEEFEC;
}
.sift-auto-speed, .sift-auto-speed *,
.sift-auto-speed *::before, .sift-auto-speed *::after {
  box-sizing: border-box;
}

/* ---------- 16:9 demo stage ---------- */
.sift-auto-speed.demo-stage {
  background: #131416;
  border: 1px solid #2A2C2E;
  aspect-ratio: 16 / 9;
  width: 100%;
  position: relative;
  overflow: hidden;
  color: var(--ceramic);
}
/* Dot grid behind everything. */
.sift-auto-speed .scale-wrap::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(255, 255, 255, 0.14) 1px, transparent 1px);
  background-size: 32px 32px;
  background-position: center center;
  pointer-events: none;
}

/* ---------- Scale wrap ----------
   Locks the design canvas to 664 × 374 and scales it to fit. */
.sift-auto-speed .scale-wrap {
  position: absolute;
  top: 0;
  left: 0;
  width: 664px;
  aspect-ratio: 16 / 9;
  transform-origin: top left;
  transform: scale(var(--stage-scale, 1));
}

/* ---------- Intro CTA — "Create Report" ----------
   Same scale + chrome vocabulary as the Make-a-Rule intro button. */
.sift-auto-speed .cta-intro {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, calc(-50% + 18px)) scale(1.04);
  opacity: 0;
  display: inline-flex;
  align-items: center;
  gap: 14px;
  padding: 22px 38px;
  font-family: "IBM Plex Mono", monospace;
  font-size: 22px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: #2A2C2E;
  color: var(--ceramic);
  border: 2px solid var(--steel);
  border-radius: 0;
  cursor: pointer;
  z-index: 2;
  pointer-events: none;
  transition: opacity 480ms cubic-bezier(0.2,0,0,1),
              transform 620ms cubic-bezier(0.2,0,0,1),
              background 140ms cubic-bezier(0.2,0,0,1),
              color 140ms cubic-bezier(0.2,0,0,1),
              border-color 140ms cubic-bezier(0.2,0,0,1);
}
.sift-auto-speed .cta-intro.show {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
  pointer-events: auto;
}
.sift-auto-speed .cta-intro.hover {
  background: #4B4C4A;
  color: var(--ceramic);
  border-color: #8E8A89;
}
.sift-auto-speed .cta-intro.pressed {
  transform: translate(-50%, calc(-50% + 2px)) scale(0.99);
}
.sift-auto-speed .cta-intro.gone {
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.94);
  pointer-events: none;
  transition: opacity 420ms cubic-bezier(0.2,0,0,1),
              transform 460ms cubic-bezier(0.2,0,0,1);
}
.sift-auto-speed .cta-plus {
  font-family: "IBM Plex Sans", sans-serif;
  font-size: 26px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0;
  margin-right: 2px;
  margin-top: -2px;
}

/* ---------- Report card ----------
   Grows in flow: with display:flex + flex-direction:column and no
   max-height, the intrinsic height equals the sum of the rendered items
   (title, "Rules" + tabs, rule blocks, annotation rows). New items pop
   into place at the bottom; the card's top is driven by JS to keep
   the title centered while the bottom hasn't yet reached the stage's
   bottom margin, then to pin the bottom to that margin so further
   growth pushes the whole card up off the top of the stage.

   No overflow: hidden — content above the card's top edge is allowed
   to extend out; the stage's own overflow:hidden does the final clip
   at the top of the visible area.

   The chrome (background, border, shadow) is faded in via .chrome-in
   once the container "appears" around the centered title, and is
   faded out at the end of the cycle via .fade-all on the card itself,
   which drops the whole card's opacity (chrome + every list item)
   together in one breath. */
.sift-auto-speed .report-card {
  position: absolute;
  /* Initial top position keeps the initial card (title + "Rules" + tabs)
     centered on the stage's vertical midline. A ResizeObserver in the
     React app overwrites this inline as annotations stream in:
     top = min(132, 344 - h), so once cardHeight would push the bottom
     past y≈344 the card switches to bottom-anchored and grows upward
     off the stage instead of off the bottom. */
  top: 104px;
  left: 50%;
  /* Scale the whole card 1.5×. transform-origin: top center keeps the
     visual top edge fixed at the CSS top value, so the JS top-calc
     can stay in design-space terms by just multiplying h by 1.5. */
  transform: translateX(-50%) scale(1.5);
  transform-origin: top center;
  /* Hug content: card width is driven by its widest row, which is the
     "Open / Failed / Accepted / Error" status tab strip. Rule names
     are capped at a max-width below that figure (see .rule-name) so
     they never push the card wider than the tabs. Stays horizontally
     centered in the stage via left:50% + translateX. */
  width: max-content;
  padding: 14px 16px 12px;
  background: var(--rubber-black);
  border: 1px solid #2A2C2E;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.55);
  color: var(--ceramic);
  font-family: "IBM Plex Sans", sans-serif;
  display: flex;
  flex-direction: column;
  gap: 8px;
  overflow: visible;
  /* Hidden by default — only mounted once phase >= 'title'. */
  opacity: 0;
  pointer-events: none;
  z-index: 3;
  /* Chrome starts hidden; .chrome-in fades it in. */
  background-color: transparent;
  border-color: transparent;
  box-shadow: none;
  transition: opacity 420ms cubic-bezier(0.2, 0, 0, 1),
              background-color 420ms cubic-bezier(0.2, 0, 0, 1),
              border-color 420ms cubic-bezier(0.2, 0, 0, 1),
              box-shadow 420ms cubic-bezier(0.2, 0, 0, 1);
}
.sift-auto-speed .report-card.in {
  opacity: 1;
  pointer-events: auto;
}
/* Container border + bg fade in around the title once chrome is enabled. */
.sift-auto-speed .report-card.chrome-in {
  background-color: var(--rubber-black);
  border-color: #2A2C2E;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.55);
}

/* End-of-cycle fade: a one-shot opacity transition. The .fade-all class
   sits on the card itself, so every child (header, tabs, rule heads,
   annotation entries) fades together with the chrome — one breath, not
   a layered animation. Duration matches the 1s wait in the autoplay
   loop so the fade finishes right as the cycle restarts. */
.sift-auto-speed .report-card.fade-all {
  opacity: 0;
  transition: opacity 800ms cubic-bezier(0.4, 0, 0.2, 1);
}



/* Header — first child, top of the stack. Left-aligned at all times so
   the title loads in the exact position it will hold once the rest of
   the list is revealed (no horizontal jump when the chrome fades in). */
.sift-auto-speed .report-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-bottom: 10px;
  border-bottom: 1px solid #2A2C2E;
  flex: 0 0 auto;
  transition: border-color 320ms cubic-bezier(0.2, 0, 0, 1);
  text-align: left;
}
.sift-auto-speed .report-card:not(.chrome-in) .report-head {
  border-bottom-color: transparent;
}
.sift-auto-speed .report-eyebrow {
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--lunar);
}
.sift-auto-speed .report-name {
  font-family: "IBM Plex Sans", sans-serif;
  font-size: 13px;
  font-weight: 500;
  color: var(--ceramic);
  letter-spacing: -0.005em;
}

/* "Rules" label + status tab strip. Mirrors the Automate_Rules popup. */
.sift-auto-speed .rules-section {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 0 0 auto;
}
.sift-auto-speed .rules-field-label {
  font-family: "IBM Plex Mono", monospace;
  font-size: 8.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--lunar);
}
.sift-auto-speed .rules-tabs {
  display: flex;
  align-items: center;
  gap: 3px;
}
.sift-auto-speed .rule-tab {
  font-family: "IBM Plex Mono", monospace;
  font-size: 8.5px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 2px 5px;
  border: 1px solid transparent;
  border-radius: 0;
  line-height: 1.3;
}
.sift-auto-speed .rule-tab.tab-open     { color: var(--sift-orange); background: rgba(240, 74, 1, 0.16); }
.sift-auto-speed .rule-tab.tab-failed   { color: #FA4D56;            background: rgba(250, 77, 86, 0.16); }
.sift-auto-speed .rule-tab.tab-accepted { color: #4ED49B;            background: rgba(78, 212, 155, 0.16); }
.sift-auto-speed .rule-tab.tab-error    { color: #FCC539;            background: rgba(252, 197, 57, 0.18); }

/* Each rule group */
.sift-auto-speed .report-rule {
  margin-top: 8px;
  border-top: 1px solid #2A2C2E;
  padding-top: 8px;
  flex: 0 0 auto;
  /* Each rule block fades in as it gets mounted (since it's conditionally
     rendered, no CSS-only state — we animate via @keyframes). */
  animation: sift-auto-speed-fade-in 360ms cubic-bezier(0.2, 0, 0, 1) both;
}

/* Rule head — flush orange stroke on the left. */
.sift-auto-speed .rule-head {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 8px;
  border-left: 2px solid var(--sift-orange);
  background: transparent;
  font-size: 11px;
  color: var(--ceramic);
  cursor: pointer;
  transition: background 140ms cubic-bezier(0.2, 0, 0, 1);
}
.sift-auto-speed .rule-head:hover {
  background: rgba(255, 255, 255, 0.08);
}
.sift-auto-speed .rule-name {
  font-weight: 500;
  flex: 1 1 auto;
  min-width: 0;
  /* Cap at less than the natural width of the tabs row above so a long
     rule name never widens the card past the status strip. */
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Annotation list */
.sift-auto-speed .rule-list {
  margin-top: 6px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-left: 16px;
}
.sift-auto-speed .anno-entry {
  display: flex;
  align-items: center;
  padding: 4px 8px;
  border-left: 2px solid var(--sift-orange);
  background: transparent;
  font-family: "IBM Plex Mono", monospace;
  font-size: 9.5px;
  color: var(--gray-30);
  letter-spacing: 0.04em;
  cursor: pointer;
  /* Annotations are mounted conditionally; keyframe fade-in. */
  animation: sift-auto-speed-fade-in 260ms cubic-bezier(0.2, 0, 0, 1) both;
  transition: background 140ms cubic-bezier(0.2, 0, 0, 1),
              color 140ms cubic-bezier(0.2, 0, 0, 1);
}
.sift-auto-speed .anno-entry:hover {
  background: rgba(255, 255, 255, 0.08);
  color: var(--ceramic);
}

@keyframes sift-auto-speed-fade-in {
  from { opacity: 0; transform: translateY(3px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ---------- Demo cursor ---------- */
.sift-auto-speed .cursor {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  opacity: 0;
  z-index: 5;
  pointer-events: none;
  transition: transform 620ms cubic-bezier(0.2, 0, 0, 1),
              opacity 280ms ease-out;
}
.sift-auto-speed .cursor.visible { opacity: 1; }
.sift-auto-speed .cursor-icon {
  position: absolute;
  pointer-events: none;
  filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.55));
}
.sift-auto-speed .cursor-icon.arrow {
  /* Arrow tip is at SVG (10,7), so a 44px icon needs to be offset by
     (-13.75, -9.625) to land the tip at the wrapper origin. */
  width: 44px; height: 44px;
  top: -9.625px;
  left: -13.75px;
  transform-origin: 13.75px 9.625px;
}
/* Click pulse — icon dips and returns over 220ms. */
.sift-auto-speed .cursor.clicking .cursor-icon.arrow {
  animation: sift-auto-speed-cursor-click 220ms cubic-bezier(0.2, 0, 0, 1);
}
@keyframes sift-auto-speed-cursor-click {
  0%   { transform: scale(1); }
  45%  { transform: scale(0.82); }
  100% { transform: scale(1); }
}

