/* ============================================================
   TENARIE — Product Story Graphics (shared)
   Animated CSS/SVG abstractions of real Tenarie screens, used in
   place of static screenshots on the marketing site and the product
   presentation deck. Self-contained: carries the design tokens it
   needs so it works standalone (e.g. linked into presentation.css).
   Rendered via public_app/includes/feature_graphic.html.
   ============================================================ */

:root {
  /* Color palette — aligned with platform brand (saas.css) */
  --color-navy:       #0f172a;
  --color-navy-light: #1a2a45;
  --color-navy-mid:   #253754;
  --color-slate:      #3d506b;
  --color-steel:      #6b7c95;
  --color-mist:       #a8b5c8;
  --color-cloud:      #d6dde8;
  --color-ice:        #eef1f6;
  --color-white:      #ffffff;
  --color-border-soft:#e3e8f0;

  --color-accent:      #4384a8;
  --color-accent-hover:#376f8d;
  --color-accent-soft: rgba(67, 132, 168, 0.10);
  --color-link:        #376f8d;
  --color-link-hover:  #325f78;

  /* Primary action color — matches the app's --app-action-primary. */
  --color-action:       #376f8d;
  --color-action-hover: #325f78;

  --color-success:    #16a34a;
  --color-danger:     #dc2626;

  /* Amber accent — aligned to the app's gold (--bs-warning #ffbc00). Dark text
     on amber (fails AA with white). */
  --color-highlight:    #ffca28;                    /* bright — highlighted word on the dark hero */
  --color-proof:        #ffbc00;                    /* app gold */
  --color-proof-strong: #b8860b;                    /* deeper — text / white-on-amber badges */
  --color-proof-soft:   rgba(255, 188, 0, 0.14);    /* soft tile / ambient glow fill */
  --color-proof-border: rgba(255, 188, 0, 0.35);    /* hairline borders / rings */

  /* Typography — single modern family across the marketing site. Hierarchy
     comes from weight and size rather than a separate display typeface. */
  --font-body:    'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-display: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --text-xs:   0.75rem;
  --text-sm:   0.875rem;
  --text-base: 1rem;
  --text-md:   1.125rem;
  --text-lg:   1.25rem;
  --text-xl:   1.5rem;
  --text-2xl:  2rem;
  --text-3xl:  2.5rem;
  --text-4xl:  3.25rem;
  --text-5xl:  4rem;

  /* Spacing */
  --space-xs:  0.5rem;
  --space-sm:  1rem;
  --space-md:  1.5rem;
  --space-lg:  2rem;
  --space-xl:  3rem;
  --space-2xl: 4.5rem;
  --space-3xl: 6rem;
  --space-4xl: 8rem;

  /* Layout */
  --container-max:    1200px;
  --container-narrow: 800px;

  /* Radius */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-xl: 24px;

  /* Shadows — base rgb aligned with platform (15, 23, 42) */
  --shadow-sm:  0 1px 3px rgba(15, 23, 42, 0.06);
  --shadow-md:  0 4px 12px rgba(15, 23, 42, 0.08);

  /* Layered card shadows — soft at rest, lifted on hover, for a modern feel. */
  --shadow-card:       0 1px 2px rgba(15, 23, 42, 0.04), 0 6px 20px -8px rgba(15, 23, 42, 0.10);
  --shadow-card-hover: 0 2px 5px rgba(15, 23, 42, 0.05), 0 18px 40px -14px rgba(15, 23, 42, 0.20);
  /* Deep, diffused float — for product graphics that lift off the page. */
  --shadow-float:      0 30px 60px -24px rgba(15, 23, 42, 0.32), 0 12px 28px -18px rgba(15, 23, 42, 0.16);

  /* Card hover ring — from platform .workspace-card:hover (saas.css) */
  --ring-accent: 0 0 0 2px rgba(67, 132, 168, 0.35);

  /* Transitions — aligned with platform 0.2s ease-in-out */
  --ease: ease-in-out;
  --duration: 0.2s;
}

/* ============================================================
   PRODUCT STORY GRAPHICS
   Animated CSS/SVG abstractions of real Tenarie screens, used in
   place of static screenshots. Each loops a short "story"; all are
   frozen to a readable still under prefers-reduced-motion (below).
   ============================================================ */
.ui-mock {
  position: relative;
  width: 100%;
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border-soft);
  background: var(--color-white);
  box-shadow: var(--shadow-float), inset 0 1px 0 rgba(255, 255, 255, 0.85);
  overflow: hidden;
}

/* ---- PROOF: test-package (maturity rings + pass/fail tests) ---- */
.ui-mock {
  padding: var(--space-lg);
}

/* Full-bleed toolbar header, tinted like real app chrome. */
.ui-mock-bar {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin: calc(var(--space-lg) * -1) calc(var(--space-lg) * -1) var(--space-md);
  padding: var(--space-sm) var(--space-lg);
  background: linear-gradient(180deg, var(--color-ice), var(--color-white));
  border-bottom: 1px solid var(--color-border-soft);
}

.ui-mock-search {
  flex: 1;
  min-width: 0;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--color-navy);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  background: var(--color-white);
  border: 1px solid var(--color-border-soft);
  border-radius: 999px;
  padding: 6px 12px;
}

.ui-mock-tag {
  flex-shrink: 0;
  font-size: 0.65rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-accent);
  background: var(--color-accent-soft);
  padding: 3px 8px;
  border-radius: 999px;
}

.ui-rings {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--space-xs);
  margin-bottom: var(--space-md);
}

.ui-ring {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.ui-ring svg {
  width: 100%;
  max-width: 46px;
  aspect-ratio: 1;
}

.ui-ring-track {
  fill: none;
  stroke: var(--color-ice);
  stroke-width: 4;
}

/* Progress arc. r=15.915 makes the circumference exactly 100, so the fill
   target is simply (100 − percent), supplied per ring as inline --dash. */
.ui-ring-val {
  fill: none;
  stroke: var(--color-success);
  stroke-width: 4;
  stroke-linecap: round;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  transform: rotate(-90deg);
  transform-origin: 50% 50%;
  animation: ui-ring-fill 5.5s var(--ease) infinite;
}

.ui-ring-amber .ui-ring-val { stroke: var(--color-proof); }

.ui-ring:nth-child(2) .ui-ring-val { animation-delay: .25s; }
.ui-ring:nth-child(3) .ui-ring-val { animation-delay: .5s; }
.ui-ring:nth-child(4) .ui-ring-val { animation-delay: .75s; }
.ui-ring:nth-child(5) .ui-ring-val { animation-delay: 1s; }
.ui-ring:nth-child(6) .ui-ring-val { animation-delay: 1.25s; }

.ui-ring span {
  font-size: 0.6rem;
  font-weight: 600;
  color: var(--color-steel);
}

@keyframes ui-ring-fill {
  0%        { stroke-dashoffset: 100; }
  18%, 86%  { stroke-dashoffset: var(--dash); }
  100%      { stroke-dashoffset: 100; }
}

.ui-tests {
  display: grid;
  gap: 10px;
}

.ui-test {
  display: grid;
  align-items: center;
  gap: var(--space-sm);
  padding: 10px var(--space-sm);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
}

/* Fixed columns so the function tags and Pass/Fail badges line up down the rows. */
.ui-tests-2 .ui-test { grid-template-columns: minmax(0, 1fr) 6rem; }
.ui-tests-3 .ui-test { grid-template-columns: minmax(0, 1fr) 3.75rem 3rem; }

.ui-test > .ui-badge,
.ui-test > .ui-tag { justify-self: start; }

.ui-badge {
  flex-shrink: 0;
  font-size: 0.62rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
  padding: 3px 9px;
  border-radius: 999px;
  animation: ui-badge-in 5.5s var(--ease) infinite;
}

.ui-badge-pass { color: var(--color-success); background: rgba(22, 163, 74, 0.12); }
.ui-badge-fail { color: var(--color-danger);  background: rgba(220, 38, 38, 0.12); }

.ui-test:nth-child(1) .ui-badge { animation-delay: 1.4s; }
.ui-test:nth-child(2) .ui-badge { animation-delay: 1.7s; }
.ui-test:nth-child(3) .ui-badge { animation-delay: 2s; }

@keyframes ui-badge-in {
  0%, 22%  { opacity: 0; transform: translateY(4px) scale(.85); }
  32%, 88% { opacity: 1; transform: none; }
  100%     { opacity: 0; transform: translateY(4px) scale(.85); }
}

/* ---- FEATURE-PAGE ARCHETYPES ----
   Reusable graphic bodies (register, tasks, charts, flow, spaces) shown on the
   features hub and feature detail pages. Each shares the .ui-mock panel and a
   header carrying the feature's real icon and name. Assurance reuses the rings
   and pass/fail rows from the landing test-package graphic above. */
.ui-mock-ico { display: inline-flex; flex-shrink: 0; }
.ui-mock-bar .public-card-icon { margin: 0; }
.ui-mock-bar .public-card-icon svg { width: 18px; height: 18px; }

.ui-badge-warn  { color: var(--color-proof-strong); background: var(--color-proof-soft); }
.ui-badge-info  { color: var(--color-accent);        background: var(--color-accent-soft); }
.ui-badge-muted { color: var(--color-steel);         background: var(--color-ice); }

/* Outline "function" tag beside test rows (e.g. Protect / Identify). */
.ui-tag {
  flex-shrink: 0;
  font-size: 0.58rem;
  font-weight: 600;
  color: var(--color-steel);
  border: 1px solid var(--color-border-soft);
  border-radius: 5px;
  padding: 2px 6px;
  white-space: nowrap;
}

/* Register: rows of records — code chip, title/subtitle and status badges. A
   soft highlight sweeps down the rows to imply live, updating data. */
.ui-reg { display: grid; gap: 8px; }

.ui-reg-row {
  display: grid;
  align-items: center;
  gap: var(--space-sm);
  padding: 9px var(--space-sm);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
  animation: ui-reg-scan 5.5s var(--ease) infinite;
}
.ui-reg-row:nth-child(2) { animation-delay: .5s; }
.ui-reg-row:nth-child(3) { animation-delay: 1s; }
.ui-reg-row:nth-child(4) { animation-delay: 1.5s; }

/* Fixed columns per register type so codes and badges line up down the rows. */
.ui-reg-reference .ui-reg-row { grid-template-columns: 4.5rem minmax(0, 1fr); }
.ui-reg-controls  .ui-reg-row { grid-template-columns: 3rem minmax(0, 1fr) 7rem; }
.ui-reg-risk      .ui-reg-row { grid-template-columns: minmax(0, 1fr) 3.75rem 6rem; }
.ui-reg-asset     .ui-reg-row { grid-template-columns: minmax(0, 1fr) 2.75rem 5rem; }

/* Trailing items hug the left of their fixed column so they align vertically. */
.ui-reg-code,
.ui-reg-dots,
.ui-reg-row > .ui-badge { justify-self: start; }

/* Badges stay still in a register — the row highlight carries the motion. */
.ui-reg .ui-badge {
  animation: none;
  opacity: 1;
  transform: none;
  white-space: nowrap;
}

.ui-reg-code {
  flex-shrink: 0;
  font-size: 0.6rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--color-accent);
  background: var(--color-accent-soft);
  border-radius: 5px;
  padding: 3px 6px;
}

.ui-reg-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow: hidden;
}

.ui-reg-title {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--color-navy);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ui-reg-sub {
  font-size: 0.6rem;
  color: var(--color-steel);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ui-reg-dots { flex-shrink: 0; display: inline-flex; gap: 4px; }
.ui-reg-dots i { width: 7px; height: 7px; border-radius: 50%; }

.ui-dot-pass { background: var(--color-success); }
.ui-dot-warn { background: var(--color-proof); }
.ui-dot-fail { background: var(--color-danger); }
.ui-dot-mute { background: var(--color-cloud); }
.ui-dot-info { background: var(--color-accent); }

@keyframes ui-reg-scan {
  0%, 100% { background-color: transparent; }
  8%       { background-color: var(--color-accent-soft); }
  22%      { background-color: transparent; }
}

/* Assurance mapping stats (Records / MITRE / Controls). Reuses .ui-stat cells. */
.ui-statcards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-xs);
  margin-bottom: var(--space-md);
}

/* Tasks: stat counters over a short task list. */
.ui-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-xs);
  margin-bottom: var(--space-md);
}

.ui-stat {
  text-align: center;
  padding: var(--space-sm) 4px;
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
}

.ui-stat b {
  display: block;
  font-size: var(--text-xl);
  font-weight: 800;
  line-height: 1;
  color: var(--color-navy);
  animation: ui-stat-in 5.5s var(--ease) infinite;
}
.ui-stat:nth-child(2) b { animation-delay: .15s; }
.ui-stat:nth-child(3) b { animation-delay: .3s; }
.ui-stat:nth-child(4) b { animation-delay: .45s; }

.ui-stat span {
  font-size: 0.55rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-steel);
}

@keyframes ui-stat-in {
  0%, 6%   { opacity: 0; transform: translateY(6px) scale(.8); }
  16%, 90% { opacity: 1; transform: none; }
  100%     { opacity: 0; transform: translateY(6px) scale(.8); }
}

/* Charts: a mini insights dashboard — KPI tiles, a bar chart with gridlines,
   a maturity donut and a drawn trend sparkline. */
.ui-dash { display: grid; gap: 10px; }

.ui-kpis {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-xs);
}

.ui-kpi {
  display: grid;
  gap: 3px;
  padding: var(--space-sm);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
  background: linear-gradient(180deg, var(--color-ice), var(--color-white));
}

.ui-kpi-label {
  font-size: 0.52rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-steel);
}

.ui-kpi-num {
  font-size: var(--text-lg);
  font-weight: 800;
  line-height: 1;
  color: var(--color-navy);
  animation: ui-stat-in 5s var(--ease) infinite;
}
.ui-kpi:nth-child(2) .ui-kpi-num { animation-delay: .12s; }
.ui-kpi:nth-child(3) .ui-kpi-num { animation-delay: .24s; }

.ui-kpi-trend { font-size: 0.55rem; font-weight: 700; }
.ui-kpi-pos { color: var(--color-success); }
.ui-kpi-neg { color: var(--color-danger); }

.ui-dash-row {
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  gap: 10px;
}

.ui-panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: var(--space-sm);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
}

.ui-panel-title {
  font-size: 0.55rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-steel);
}

.ui-panel-donut { align-items: center; justify-content: center; }

.ui-bars {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  height: 100px;
}

/* Faint horizontal gridlines behind the bars. */
.ui-bars-grid {
  background-image: repeating-linear-gradient(
    to top, transparent 0, transparent 24px,
    var(--color-ice) 24px, var(--color-ice) 25px);
}

.ui-bars i {
  flex: 1;
  height: var(--h);
  border-radius: 6px 6px 0 0;
  background: linear-gradient(var(--color-accent), var(--color-accent-hover));
  transform-origin: bottom;
  animation: ui-bar-grow 4.6s var(--ease) infinite;
}
.ui-bars i:nth-child(2) { animation-delay: .12s; }
.ui-bars i:nth-child(3) { animation-delay: .24s; }
.ui-bars i:nth-child(4) { animation-delay: .36s; }
.ui-bars i:nth-child(5) { animation-delay: .48s; }
.ui-bars i.ui-bar-pass  { background: linear-gradient(var(--color-success), #12833c); }
.ui-bars i.ui-bar-warn  { background: linear-gradient(var(--color-proof), var(--color-proof-strong)); }
.ui-bars i.ui-bar-fail  { background: linear-gradient(var(--color-danger), #b91c1c); }

/* Trend sparkline: an area that fades in beneath a line that draws itself. */
.ui-spark { width: 100%; height: 46px; }
.ui-spark svg { width: 100%; height: 100%; display: block; }

.ui-spark-area {
  fill: var(--color-accent-soft);
  opacity: 0;
  animation: ui-spark-fade 5s var(--ease) infinite;
}

.ui-spark-line {
  fill: none;
  stroke: var(--color-accent);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: ui-spark-draw 5s var(--ease) infinite;
}

@keyframes ui-spark-draw {
  0%       { stroke-dashoffset: 1; }
  35%, 90% { stroke-dashoffset: 0; }
  100%     { stroke-dashoffset: 1; }
}

@keyframes ui-spark-fade {
  0%, 22%  { opacity: 0; }
  42%, 90% { opacity: 1; }
  100%     { opacity: 0; }
}

.ui-legend { display: flex; gap: var(--space-md); }
.ui-legend span {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 0.58rem;
  color: var(--color-steel);
}
.ui-legend i { width: 7px; height: 7px; border-radius: 50%; }

.ui-donut { position: relative; display: grid; place-items: center; }
.ui-donut .ui-ring svg { width: 100%; max-width: 90px; }
/* Donut arc in the app's steel-blue (the app's workspace donut reads blue). */
.ui-donut .ui-ring-val { stroke: var(--color-accent); }
.ui-donut-sm .ui-ring svg { max-width: 66px; }

.ui-donut-val {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-weight: 800;
  font-size: 0.74rem;
  color: var(--color-navy);
}
.ui-donut-sm .ui-donut-val { font-size: 0.6rem; }

@keyframes ui-bar-grow {
  0%       { transform: scaleY(0); }
  28%, 88% { transform: scaleY(1); }
  100%     { transform: scaleY(0); }
}

/* Flow: two workflow nodes joined by a line with a traveling pulse. */
.ui-flow {
  display: grid;
  justify-items: center;
  padding: var(--space-sm) 0;
}

.ui-node {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  width: 84%;
  padding: 10px var(--space-sm);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
  background: var(--color-white);
  box-shadow: var(--shadow-card);
}

.ui-flow-label {
  align-self: flex-start;
  font-size: 0.6rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-steel);
  margin-bottom: 4px;
}

.ui-node-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.ui-node-k {
  font-size: 0.55rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-accent);
}

.ui-node-title {
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--color-navy);
}

.ui-node-desc {
  font-size: 0.58rem;
  color: var(--color-steel);
}

.ui-flow-line {
  position: relative;
  width: 2px;
  height: 30px;
  background: var(--color-cloud);
}

.ui-flow-pulse {
  position: absolute;
  left: 50%;
  top: 0;
  width: 9px;
  height: 9px;
  margin-left: -4.5px;
  border-radius: 50%;
  background: var(--color-accent);
  box-shadow: 0 0 0 4px var(--color-accent-soft);
  animation: ui-pulse-travel 2.6s var(--ease) infinite;
}

@keyframes ui-pulse-travel {
  0%   { top: -4px; opacity: 0; }
  20%  { opacity: 1; }
  80%  { opacity: 1; }
  100% { top: 30px; opacity: 0; }
}

/* Spaces: a workspace maturity ring over a grid of application cards. */
.ui-spaces { display: grid; gap: 10px; }

/* Workspace switcher — conveys multiple workspaces / organizations. */
.ui-ws-tabs {
  display: flex;
  gap: 6px;
  overflow: hidden;
}

.ui-ws-tab {
  flex-shrink: 0;
  font-size: 0.58rem;
  font-weight: 600;
  color: var(--color-steel);
  background: var(--color-ice);
  border: 1px solid var(--color-border-soft);
  border-radius: 999px;
  padding: 4px 10px;
  white-space: nowrap;
}

.ui-ws-tab-active {
  color: var(--color-accent);
  background: var(--color-accent-soft);
  border-color: var(--color-accent);
}

/* Small section captions inside the workspace (Frameworks / Applications). */
.ui-spaces-label {
  font-size: 0.55rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-steel);
}

/* Framework card holding the maturity donut and coverage percentages. */
.ui-spaces-head {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
  background: var(--color-white);
  box-shadow: var(--shadow-sm);
}

.ui-space-body {
  flex: 1;
  min-width: 0;
  display: grid;
  gap: 8px;
}

.ui-space-fw {
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--color-navy);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ui-spaces-lines {
  display: grid;
  gap: 6px;
}

.ui-space-stat {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  font-size: 0.62rem;
}

.ui-space-stat-k {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  color: var(--color-steel);
}
.ui-space-stat-k i {
  flex-shrink: 0;
  width: 7px;
  height: 7px;
  border-radius: 50%;
}

.ui-space-stat b {
  flex-shrink: 0;
  min-width: 2.5rem;
  text-align: right;
  font-weight: 700;
  color: var(--color-navy);
  font-variant-numeric: tabular-nums;
}

.ui-cards {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-xs);
}

.ui-card2 {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  padding: var(--space-sm);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
  animation: ui-card-in 5.5s var(--ease) infinite;
}
.ui-card2:nth-child(2) { animation-delay: .12s; }
.ui-card2:nth-child(3) { animation-delay: .24s; }
.ui-card2:nth-child(4) { animation-delay: .36s; }

.ui-card2-ico {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--color-ice);
  color: var(--color-accent);
}
.ui-card2-ico svg { width: 15px; height: 15px; }

.ui-card2-name {
  width: 100%;
  font-size: 0.58rem;
  font-weight: 600;
  color: var(--color-navy);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

@keyframes ui-card-in {
  0%, 8%   { opacity: 0; transform: translateY(6px); }
  18%, 90% { opacity: 1; transform: none; }
  100%     { opacity: 0; transform: translateY(6px); }
}

/* Freeze both graphics to a coherent, readable still for reduced motion. */
@media (prefers-reduced-motion: reduce) {
  .ui-ring-val   { animation: none; stroke-dashoffset: var(--dash); }
  .ui-badge      { animation: none; opacity: 1; transform: none; }
  .ui-reg-row    { animation: none; background-color: transparent; }
  .ui-stat b     { animation: none; opacity: 1; transform: none; }
  .ui-bars i     { animation: none; transform: none; }
  .ui-kpi-num    { animation: none; opacity: 1; transform: none; }
  .ui-spark-area { animation: none; opacity: 1; }
  .ui-spark-line { animation: none; stroke-dashoffset: 0; }
  .ui-flow-pulse { animation: none; opacity: 0; }
  .ui-card2      { animation: none; opacity: 1; transform: none; }
  .showcase-image .ui-mock { animation: none; }
}

@media (max-width: 768px) {
  /* On small screens the graphic is full-width, so the glow must not bleed past
     the viewport (that caused horizontal scroll). Keep vertical bleed only, and
     drop the stacked backing card to reduce clutter. */
  .showcase-image::before,
  .trust-image::before,
  .feature-row-media::before {
    inset: -8% 0;
  }
  .showcase-image::after,
  .feature-row-media::after {
    display: none;
  }
}

@media (max-width: 480px) {
  .ui-mock { padding: var(--space-sm); }
  .ui-bars { height: 96px; }

  /* Rings wrap to two roomy rows instead of six cramped columns. */
  .ui-rings { grid-template-columns: repeat(3, 1fr); gap: 10px 4px; }

  /* Register / test rows: let the badges size to their content and drop the
     secondary subtitles and function tags so the record titles have real room
     (fixed rem columns were squeezing titles to ~66px). */
  .ui-reg-reference .ui-reg-row { grid-template-columns: auto minmax(0, 1fr); }
  .ui-reg-controls .ui-reg-row { grid-template-columns: auto minmax(0, 1fr) auto; }
  .ui-reg-risk .ui-reg-row,
  .ui-reg-asset .ui-reg-row { grid-template-columns: minmax(0, 1fr) auto auto; }
  .ui-tests-2 .ui-test,
  .ui-tests-3 .ui-test { grid-template-columns: minmax(0, 1fr) auto; }

  .ui-reg-sub,
  .ui-tag { display: none; }
}


/* ---------- GRAPHIC STAGE ----------
   Lifts each animated product graphic off the page: a soft dual-tone glow
   behind it, a faint stacked "card behind the card" for depth, and (on the
   featured graphics) a gentle float so it parallaxes against its own glow. */
.showcase-image,
.trust-image,
.feature-row-media {
  position: relative;
}

.showcase-image > *,
.trust-image > *,
.feature-row-media > * {
  position: relative;
  z-index: 1;
}

.showcase-image::before,
.trust-image::before,
.feature-row-media::before {
  content: '';
  position: absolute;
  z-index: 0;
  inset: -16% -12%;
  background:
    radial-gradient(46% 52% at 30% 28%, var(--color-accent-soft), transparent 70%),
    radial-gradient(44% 50% at 74% 78%, var(--color-proof-soft), transparent 72%);
  filter: blur(22px);
  pointer-events: none;
}

.trust-image-certification::before {
  display: none;
}

/* Stacked panel behind the graphic (light sections only). */
.showcase-image::after,
.feature-row-media::after {
  content: '';
  position: absolute;
  z-index: 0;
  left: 6%;
  right: 6%;
  top: 11%;
  bottom: -7%;
  border-radius: var(--radius-lg);
  background: var(--color-white);
  border: 1px solid var(--color-border-soft);
  box-shadow: 0 24px 44px -28px rgba(15, 23, 42, 0.28);
  pointer-events: none;
}

/* Featured graphics (landing + feature detail) drift gently against their glow;
   the hub list stays still to avoid many panels bobbing at once. */
.showcase-image .ui-mock {
  animation: ui-float 7s ease-in-out infinite;
}

@keyframes ui-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-9px); }
}

/* ---------- PRESENTATION DECK WRAPPER ----------
   On the slide deck the graphic sits in .pres-screenshot, which supplies its
   own frame. Let the graphic's own card be the frame instead, and just center
   and size it. */
.pres-screenshot:has(.ui-mock) {
  max-width: 680px;
  overflow: visible;
  border-radius: 0;
  box-shadow: none;
}
