/* Foveacast stylesheet — Precision Lens design system.
 *
 * Dark-first. Custom properties carry the colour palette so a single
 * :root block defines the entire visual language.
 *
 * Accessibility contracts (all pairs verified, WCAG 2.1 AA):
 *   --fc-on-surface (#dce2f7) on --fc-surface (#0c1322)      ≈ 14.4:1  ✓
 *   --fc-primary (#b4c5ff) on --fc-surface (#0c1322)         ≈ 10.9:1  ✓
 *   --fc-on-surface-variant (#c3c6d7) on --fc-surface-low    ≈ 8.2:1   ✓
 *   --fc-primary (#b4c5ff) on --fc-surface-container (#191f2f) ≈ 10.3:1 ✓
 *   Focus ring (#ffcc33 / #ffbf00) meets 3:1 on all dark surfaces.
 *
 * Layout:
 *   Topnav: fixed, 64 px tall, full-width, z-index 100.
 *   Sidebar: fixed, 256 px wide, from topnav bottom to viewport bottom,
 *            z-index 90. Hidden below 900 px (mobile/narrow desktop).
 *   Main: margin-left 256 px, padding-top 64 px. Collapses to no
 *         margin below 900 px.
 *
 * Motion: all durations are custom-property-driven. A single
 *   prefers-reduced-motion block at the end zeroes them.
 */

/* -- Design tokens ------------------------------------------------------- */

:root {
  /* Surfaces — stacked depth levels from darkest (base) to lightest. */
  --fc-base:               #070e1d;  /* surface-container-lowest */
  --fc-surface:            #0c1322;  /* base background */
  --fc-surface-low:        #141b2b;  /* sidebar / nav */
  --fc-surface-mid:        #191f2f;  /* cards, main workspace */
  --fc-surface-high:       #232a3a;  /* raised cards */
  --fc-surface-highest:    #2e3545;  /* floating panels, tooltips */
  --fc-surface-bright:     #323949;  /* glass panels */

  /* Typography */
  --fc-on-surface:         #dce2f7;  /* 14.4:1 on --fc-surface */
  --fc-on-surface-variant: #c3c6d7;  /* 8.2:1 on --fc-surface-low */
  --fc-on-surface-dim:     #8d90a0;  /* 4.6:1 on --fc-surface-low — large text only */

  /* Accent — electric blue */
  --fc-primary:            #b4c5ff;  /* 10.9:1 on --fc-surface */
  --fc-primary-container:  #0052d9;  /* interactive backgrounds */
  --fc-on-primary:         #002a78;  /* text on primary-container */

  /* Semantic */
  --fc-success:            #3fc27a;
  --fc-danger:             #ffb4ab;  /* 10.3:1 on --fc-surface */
  --fc-warning:            #ffcc33;  /* also used as focus ring */

  /* Borders */
  --fc-outline:            #8d90a0;
  --fc-outline-variant:    #434654;

  /* Focus ring */
  --fc-focus:              #ffcc33;

  /* Radii */
  --fc-radius:             12px;
  --fc-radius-sm:          6px;
  --fc-radius-full:        999px;

  /* Layout */
  --fc-topnav-h:           64px;
  --fc-sidebar-w:          256px; /* retained as a reference; sidebar removed in single-column redesign */
  --fc-toolbar-h:          80px;

  /* Shadows — tinted to background hue, not pure black. */
  --fc-shadow-ambient:     0 4px 24px rgba(7, 14, 29, 0.5);
  --fc-shadow-subtle:      0 1px 4px rgba(7, 14, 29, 0.3);

  /* Motion */
  --fc-dur-fast:           120ms;
  --fc-dur-med:            240ms;
  --fc-ease:               cubic-bezier(0.22, 0.61, 0.36, 1);

  color-scheme: dark;
}

/* -- Base ---------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
}

body {
  background: var(--fc-surface);
  color: var(--fc-on-surface);
  font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 1rem;
  line-height: 1.5;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

p {
  margin: 0 0 0.75em;
}

h1, h2, h3 {
  margin: 0 0 0.4em;
  line-height: 1.2;
  letter-spacing: -0.02em;
}

a {
  color: var(--fc-primary);
  text-decoration: underline;
  text-underline-offset: 2px;
}

a:hover {
  color: var(--fc-on-surface);
}

/* The HTML `hidden` attribute is overridable by author display rules;
   this rule ensures it always wins so progressive disclosure works. */
[hidden] {
  display: none !important;
}

/* Focus ring — high-contrast amber, visible on every dark surface. */
:focus-visible {
  outline: 3px solid var(--fc-focus);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Skip link — visible only when keyboard-focused. */
.fc-skiplink {
  position: fixed;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--fc-primary-container);
  color: #ffffff;
  padding: 0.5rem 0.9rem;
  border-radius: 0 0 var(--fc-radius-sm) 0;
  font-weight: 700;
  text-decoration: none;
  font-size: 0.875rem;
  letter-spacing: 0.02em;
}

.fc-skiplink:focus {
  left: 0;
}

/* -- App shell ----------------------------------------------------------- */

#fc-app {
  min-height: 100vh;
}

/* -- Top navigation bar -------------------------------------------------- */

.fc-topnav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: var(--fc-topnav-h);
  z-index: 100;
  background: var(--fc-surface);
  /* Subtle bottom shadow to lift nav above content. */
  box-shadow: 0 1px 0 var(--fc-outline-variant);

  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 2rem;
  gap: 2rem;
}

.fc-topnav__brand {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* Isometric cube logo mark — size and tint matching the wordmark. */
.fc-topnav__logo-mark {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  color: var(--fc-primary);
}

.fc-topnav__wordmark {
  font-size: 1.1rem;
  font-weight: 900;
  letter-spacing: -0.03em;
  color: var(--fc-primary);
}

.fc-topnav__links {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  flex: 1;
}

.fc-topnav__link {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
  color: var(--fc-on-surface-variant);
  padding: 0.4rem 0.75rem;
  border-radius: var(--fc-radius-sm);
  transition: color var(--fc-dur-fast) var(--fc-ease),
              background var(--fc-dur-fast) var(--fc-ease);
}

.fc-topnav__link:hover {
  color: var(--fc-on-surface);
  background: var(--fc-surface-mid);
}

.fc-topnav__link--active {
  color: var(--fc-primary);
  border-bottom: 2px solid var(--fc-primary-container);
  border-radius: 0;
  padding-bottom: 0.3rem;
}

.fc-topnav__link--active:hover {
  background: transparent;
  color: var(--fc-primary);
}

.fc-topnav__actions {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.fc-topnav__help {
  background: transparent;
  border: none;
  color: var(--fc-primary);
  padding: 0.5rem;
  border-radius: var(--fc-radius-sm);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--fc-dur-fast) var(--fc-ease);
}

.fc-topnav__help:hover {
  background: var(--fc-surface-mid);
}

/* Thin indeterminate loading bar along the bottom edge of the topnav.
   Activated by adding .fc-topnav--busy to the nav element from main.js
   whenever a model load or inference run is in flight.
   The sweep animation is automatically zeroed by prefers-reduced-motion. */
.fc-topnav__loader {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 3px;
  overflow: hidden;
  pointer-events: none;
}

.fc-topnav__loader::after {
  content: '';
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 50%;
  background: linear-gradient(
    90deg,
    transparent 0%,
    var(--fc-primary) 40%,
    var(--fc-primary-container) 60%,
    transparent 100%
  );
  transform: translateX(-120%);
}

.fc-topnav--busy .fc-topnav__loader::after {
  animation: fc-loader-sweep 1.4s ease-in-out infinite;
}

@keyframes fc-loader-sweep {
  0%   { transform: translateX(-120%); }
  100% { transform: translateX(280%); }
}

/* -- Main workspace ------------------------------------------------------- */

.fc-main {
  /* why: no sidebar offset in the single-column design; centred instead. */
  max-width: 960px;
  margin-left: auto;
  margin-right: auto;
  /* scroll-margin-top ensures the #fc-main anchor (skip link target)
     is not hidden under the fixed topnav. */
  scroll-margin-top: var(--fc-topnav-h);

  min-height: 100vh;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  padding: calc(var(--fc-topnav-h) + 2rem) 2rem 2rem;

  /* why: required so .fc-voxel-bg (position: absolute) anchors to this
     column rather than the viewport or a higher ancestor. */
  position: relative;
}

/* -- Voxel background decoration ------------------------------------------ */

/*
 * .fc-voxel-bg is a purely decorative, aria-hidden SVG container driven by
 * ui/voxel-bg.js. It renders the same heatmap oblate-spheroid eye as the hero
 * logo. Pointer-events: none throughout.
 *
 * State classes applied by voxel-bg.js:
 *   .fc-voxel-bg--loading  →  prominent, centred, full-opacity (spinning eye)
 *   .fc-voxel-bg--ready    →  hidden in rest container (opacity: 0)
 *   .fc-voxel-bg--spinning →  CSS-animated during inference runs
 */
.fc-voxel-bg {
  /* Default colouring — heerich writes stroke as an SVG presentation
     attribute, so CSS custom properties (var()) won't resolve inside
     it. We set `color` here and the heerich style config uses
     `currentColor` so the design token propagates via the cascade. */
  color: var(--fc-primary);
  pointer-events: none;
}

.fc-voxel-bg svg {
  /* The heerich SVG is unitless; scale it to a visible size. */
  width: 260px;
  height: 260px;
  display: block;
}

/*
 * In-overlay variant — while the model is loading, .fc-voxel-bg lives
 * inside .fc-busy-overlay__card and IS the loading indicator. Full-opacity,
 * centred in the card. ui/voxel-bg.js re-parents the element into .fc-main
 * once the model is ready, at which point the rules below take over.
 */
.fc-busy-overlay__card .fc-voxel-bg {
  position: relative;
  width: 220px;
  height: 220px;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 1;
}

.fc-busy-overlay__card .fc-voxel-bg svg {
  width: 220px;
  height: 220px;
}

/*
 * Inference-time spin — applied to the SVG via the `--spinning` class
 * by ui/voxel-bg.js when an analysis run starts. Driven by CSS rather
 * than a JS rAF loop because ONNX inference blocks the main thread,
 * which would freeze any JS-driven animation. Compositor-thread
 * `transform` keeps ticking even while the main thread is busy with
 * the model.
 */
@keyframes fc-voxel-spin {
  to { transform: rotate(360deg); }
}

.fc-voxel-bg.fc-voxel-bg--spinning svg {
  transform-origin: 50% 50%;
  animation: fc-voxel-spin 4s linear infinite;
  /* will-change is a hint that promotes the SVG to its own layer so
     the rotation is composited rather than re-rasterised each tick. */
  will-change: transform;
}

@media (prefers-reduced-motion: reduce) {
  .fc-voxel-bg.fc-voxel-bg--spinning svg {
    animation: none;
  }
}

/*
 * Rest-state variant — once re-parented into .fc-main, the element is hidden
 * (opacity: 0). The hero logo fills the decorative background role; this
 * element only reappears via activate() during inference runs.
 */
.fc-main > .fc-voxel-bg {
  position: fixed;
  /* Defensive defaults; --ready overrides bottom/right. */
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 0;
  opacity: 0;
  transition: opacity 1s ease;
  pointer-events: none;
}

.fc-main > .fc-voxel-bg.fc-voxel-bg--loading {
  opacity: 0.45;
}

.fc-main > .fc-voxel-bg.fc-voxel-bg--ready {
  /* why: ambient decoration removed — the sticky hero logo now fills this
     role. The element stays in the DOM for the analysis-run spinner below. */
  opacity: 0;
}

/* Restore visibility during active inference so the spin indicator works. */
.fc-main > .fc-voxel-bg.fc-voxel-bg--ready.fc-voxel-bg--spinning {
  opacity: 0.45;
}

/* Ensure flex children stacked after .fc-voxel-bg sit on top of it. */
.fc-main > *:not(.fc-voxel-bg) {
  position: relative;
  z-index: 1;
}

@media (prefers-reduced-motion: reduce) {
  .fc-main > .fc-voxel-bg {
    transition: none;
  }
}

/*
 * .fc-main--has-toolbar was used when the bottom toolbar contained
 * permanent controls. The toolbar now only appears transiently during
 * background loading, so no permanent padding-bottom is needed.
 */

.fc-main:focus {
  outline: none; /* Focus moves here programmatically after inference;
                    the output-section ring carries the visual cue. */
}

.fc-mount:empty {
  display: none;
}

/* -- Workspace header ----------------------------------------------------- */

.fc-workspace-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 1rem;
}

/*
 * Title-wrap stacking context — required so that the hero logo (z-index:-1)
 * stays BEHIND the heading text but still ABOVE the page background.
 * Without an explicit z-index here, z-index:-1 would fall below the nearest
 * ancestor stacking context and disappear behind the page background.
 */
.fc-workspace-header__title-wrap {
  position: relative;
  z-index: 0;
}

.fc-workspace-header__eyebrow {
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  color: var(--fc-primary);
  margin: 0 0 0.25rem;
}

/*
 * Sticky hero logo host — zero-height position:sticky wrapper.
 * Sits in the document flow between the topnav and <main>; because it has
 * no height, it creates no layout gap. As the user scrolls, the host locks
 * at `top` (just below the topnav) and the logo inside it stays in view for
 * the rest of the page. pointer-events:none lets clicks fall through to
 * content behind; the .fc-hero-logo child re-enables its own events.
 */
.fc-hero-logo-host {
  position: sticky;
  top: calc(var(--fc-topnav-h) + 20px);
  height: 0;
  overflow: visible;
  pointer-events: none;
  /* z-index:0 keeps the host in the normal stacking order so content
     painted after it (main) naturally renders on top. */
  z-index: 0;
}

/*
 * Hero logo — absolutely positioned within the zero-height host.
 * right:-20px lets the structure bleed slightly off the right viewport
 * edge for a more organic, cropped-in feel. pointer-events:auto re-enables
 * drag-to-spin interaction on the logo itself despite the host being none.
 */
.fc-hero-logo {
  position: absolute;
  right: -20px;
  top: 0;
  /*
   * Fluid size: holds at 380 px up to a 1200 px viewport, then grows
   * linearly at 0.25× the extra viewport width, capped at 600 px (~2080
   * px viewport). Keeps narrow layouts unchanged, fills the wider empty
   * space on big monitors without the logo swallowing the page.
   */
  width:  clamp(380px, calc(380px + (100vw - 1200px) * 0.25), 600px);
  height: clamp(380px, calc(380px + (100vw - 1200px) * 0.25), 600px);
  opacity: 0.85;
  cursor: grab;
  /* why: prevent the page scrolling during a horizontal drag gesture */
  touch-action: none;
  /* why: prevent text becoming selected while dragging over the element */
  user-select: none;
  pointer-events: auto;
  color: var(--fc-primary);
}

.fc-hero-logo:focus-visible {
  outline: 2px solid var(--fc-primary);
  outline-offset: 4px;
}

/* Dimmed when auto-spin is paused via click/tap. */
.fc-hero-logo--paused {
  opacity: 0.45;
  transition: opacity 0.3s ease;
}

/* Hide on narrow viewports where 380 px would crowd content. */
@media (max-width: 719px) {
  .fc-hero-logo {
    display: none;
  }
}

/* -- Landing state layout -------------------------------------------------
 *
 * When the drop zone is visible (pre-inference), align the content column
 * with the hero logo and vertically centre it so the page feels balanced.
 *
 * Right-padding formula: max(2rem, 840px − 50vw)
 * The hero logo host spans the full viewport and positions the logo with
 * right: -20px (380 px wide). Its left edge is always at vw − 360 px.
 * The .fc-main content box right edge = (vw − 960)/2 + 960 − pr.
 * Setting those equal: pr = 840px − 50vw. max(2rem, …) floors at the
 * default side padding so the formula does nothing on viewports > 1680 px.
 *
 * justify-content: center collapses the large blank area below the drop
 * zone by vertically centring the compact landing content in the viewport.
 * padding-top: var(--fc-topnav-h) just clears the fixed nav bar; the 2 rem
 * breathing room comes from the centering algorithm instead of padding.
 */
@media (min-width: 960px) {
  .fc-main:has(.fc-drop-row:not([hidden])) {
    padding-right: max(2rem, calc(840px - 50vw));
    justify-content: center;
    padding-top: var(--fc-topnav-h);
  }
}

.fc-workspace-header__title {
  font-size: clamp(1.5rem, 2vw + 1rem, 2.5rem);
  font-weight: 900;
  letter-spacing: -0.03em;
  color: var(--fc-on-surface);
  margin: 0;
}

.fc-workspace-header__duration-label {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--fc-primary);
  margin: 0.15rem 0 0;
}

/* Etymology tag below the h1 — explains the portmanteau "fovea + cast". */
.fc-workspace-header__etymology {
  font-size: 0.78rem;
  font-style: italic;
  color: var(--fc-on-surface-variant);
  margin: 0.35rem 0 0;
  letter-spacing: 0.01em;
  line-height: 1.4;
}



/* Row that holds the button + hint; sits below the h1 in the title-wrap. */
.fc-new-upload-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 0.875rem;
}

.fc-new-upload-btn {
  font: inherit;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 0.5rem 0.9rem;
  background: transparent;
  color: var(--fc-primary);
  border: 1.5px solid var(--fc-primary);
  border-radius: var(--fc-radius-sm);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  transition:
    background var(--fc-dur-fast) var(--fc-ease),
    color var(--fc-dur-fast) var(--fc-ease),
    border-color var(--fc-dur-fast) var(--fc-ease);
}

.fc-new-upload-btn:hover:not(:disabled) {
  background: color-mix(in srgb, var(--fc-primary) 12%, transparent);
}

.fc-new-upload-btn:focus-visible {
  outline: 3px solid var(--fc-focus);
  outline-offset: 2px;
}

.fc-new-upload-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.fc-new-upload-hint {
  font-size: 0.72rem;
  color: var(--fc-on-surface-muted, color-mix(in srgb, var(--fc-on-surface) 55%, transparent));
  margin: 0;
}

/* -- Background-duration progress bar ------------------------------------ */
/*
 * Thin strip at the top of the fixed toolbar while the 1 s and 7 s models
 * load after the primary 3 s inference. Positioned inside .fc-toolbar so it
 * stays visible as the user scrolls the report. Hidden at rest (main.js
 * sets `hidden` attribute). Fill width driven from JS via showBgProgress().
 */

.fc-bg-progress {
  /* why: spans the full toolbar width above the controls row; border
     separates it visually from the topnav border-top of the toolbar */
  padding: 0.4rem var(--fc-main-px, 2rem) 0.3rem;
  border-bottom: 1px solid var(--fc-outline-variant);
}

.fc-bg-progress__track {
  height: 4px;
  background: var(--fc-surface-mid);
  border-radius: 2px;
  overflow: hidden;
}

.fc-bg-progress__fill {
  height: 100%;
  width: 0%;
  background: var(--fc-primary);
  border-radius: 2px;
  transition: width 0.35s ease;
}

.fc-bg-progress__label {
  margin: 0.25rem 0 0;
  font-size: 0.72rem;
  color: var(--fc-on-surface-variant);
}



.fc-hud {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  align-items: stretch;
}

.fc-hud__card {
  background: var(--fc-surface-low);
  border-radius: var(--fc-radius-sm);
  padding: 0.5rem 0.75rem;
  display: flex;
  flex-direction: column;
  min-width: 80px;
}

.fc-hud__label {
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0;
  color: var(--fc-on-surface-variant);
  line-height: 1.3;
}

.fc-hud__value {
  font-size: 0.95rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--fc-primary);
  line-height: 1.3;
  margin-top: 0.2rem;
}

/* HUD card tooltips — CSS-only, no JS, keyboard-accessible via focus-within */
.fc-hud__card[data-tooltip] {
  position: relative;
  cursor: help;
}

.fc-hud__card[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--fc-surface-highest);
  color: var(--fc-on-surface);
  font-size: 0.7rem;
  font-weight: 400;
  line-height: 1.4;
  padding: 0.4rem 0.6rem;
  border-radius: var(--fc-radius-sm);
  width: max-content;
  max-width: 220px;
  white-space: normal;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s ease;
  z-index: 100;
  /* prevent the card from clipping the tooltip */
  overflow: visible;
}

.fc-hud__card[data-tooltip]:hover::after,
.fc-hud__card[data-tooltip]:focus-within::after {
  opacity: 1;
}

/*
 * Rule-of-thirds breakdown — a collapsible <details> in the HUD.
 * Each cell's background intensity is driven by --cell-heat (0–1).
 */
.fc-hud__thirds {
  width: 100%;
  margin-top: 0.5rem;
}

.fc-hud__thirds > summary {
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0;
  color: var(--fc-on-surface-variant);
  cursor: pointer;
  user-select: none;
  padding: 0.25rem 0;
}

.fc-hud__thirds > summary:focus-visible {
  outline: 2px solid var(--fc-primary);
  outline-offset: 2px;
  border-radius: 2px;
}

.fc-hud__thirds-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
  margin-top: 0.35rem;
}

.fc-hud__thirds-cell {
  background: color-mix(
    in srgb,
    var(--fc-primary) calc(var(--cell-heat, 0) * 55%),
    var(--fc-surface-low)
  );
  border-radius: 2px;
  font-size: 0.65rem;
  font-variant-numeric: tabular-nums;
  color: var(--fc-on-surface);
  text-align: center;
  padding: 0.25rem 0.1rem;
  min-width: 0;
  transition: background 0.3s ease;
}

/* -- Status banner ------------------------------------------------------- */

.fc-status {
  background: var(--fc-surface-mid);
  /* why: left-border card pattern is a generic AI-slop tell; tinted
     backgrounds carry the semantic signal without the dated stripe. */
  border-radius: var(--fc-radius);
  padding: 0.9rem 1.1rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1rem;
}

.fc-status--error {
  background: color-mix(in srgb, var(--fc-danger) 8%, var(--fc-surface-mid));
}

.fc-status--ready {
  /* why: ready had no tint before — the left-border was the only visual
     distinction. Add a subtle success tint now that the border is gone. */
  background: color-mix(in srgb, var(--fc-success) 8%, var(--fc-surface-mid));
}

.fc-status--demo {
  background: color-mix(in srgb, #c97b00 8%, var(--fc-surface-mid));
}

.fc-status__body {
  margin: 0;
  flex: 1 1 280px;
  min-width: 0;
  font-size: 0.9rem;
  color: var(--fc-on-surface-variant);
}

.fc-status__progress {
  flex: 1 1 200px;
  height: 8px;
  appearance: none;
  -webkit-appearance: none;
  border: none;
  border-radius: var(--fc-radius-full);
  overflow: hidden;
  background: var(--fc-outline-variant);
}

.fc-status__progress::-webkit-progress-bar {
  background: var(--fc-outline-variant);
  border-radius: var(--fc-radius-full);
}

.fc-status__progress::-webkit-progress-value {
  background: linear-gradient(
    90deg,
    var(--fc-primary),
    var(--fc-primary-container)
  );
  border-radius: var(--fc-radius-full);
  transition: width var(--fc-dur-med) var(--fc-ease);
}

.fc-status__progress::-moz-progress-bar {
  background: var(--fc-primary);
  border-radius: var(--fc-radius-full);
}

.fc-status__progress:not([value]) {
  position: relative;
  background: linear-gradient(
    90deg,
    var(--fc-outline-variant) 0%,
    color-mix(in srgb, var(--fc-primary) 30%, var(--fc-outline-variant)) 50%,
    var(--fc-outline-variant) 100%
  );
  background-size: 200% 100%;
  animation: fc-shimmer 1.4s linear infinite;
}

@keyframes fc-shimmer {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}

.fc-status__readout {
  font-variant-numeric: tabular-nums;
  color: var(--fc-on-surface-variant);
  font-size: 0.85rem;
}

.fc-status__indicator--spin {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--fc-primary) 30%, transparent);
  border-top-color: var(--fc-primary);
  animation: fc-spin 0.8s linear infinite;
  display: inline-block;
}

.fc-status__indicator--static {
  color: var(--fc-primary);
  font-size: 1rem;
  line-height: 1;
}

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

.fc-status__retry {
  background: var(--fc-primary-container);
  color: #ffffff;
  border: none;
  border-radius: var(--fc-radius-sm);
  padding: 0.45rem 0.85rem;
  font: inherit;
  font-weight: 600;
  font-size: 0.85rem;
  cursor: pointer;
  transition: filter var(--fc-dur-fast) var(--fc-ease);
}

.fc-status__retry:hover {
  filter: brightness(1.15);
}

/* -- Drop zone ----------------------------------------------------------- */

.fc-drop-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.25rem;
}

.fc-dropzone {
  background: var(--fc-base);
  /* Ghost border — dashed at 20 % opacity per the design spec. */
  border: 2px dashed rgba(67, 70, 84, 0.9); /* --fc-outline-variant at full opacity */
  border-radius: var(--fc-radius);
  padding: clamp(2rem, 4vw, 3.5rem);
  text-align: center;
  cursor: pointer;
  transition:
    background var(--fc-dur-fast) var(--fc-ease),
    border-color var(--fc-dur-fast) var(--fc-ease),
    transform var(--fc-dur-fast) var(--fc-ease);
  position: relative;
  min-height: 220px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 0.5rem;
}

.fc-dropzone:hover {
  border-color: var(--fc-primary);
  background: color-mix(in srgb, var(--fc-primary-container) 8%, var(--fc-base));
}

.fc-dropzone:focus-visible {
  outline: 3px solid var(--fc-focus);
  outline-offset: 3px;
}

.fc-dropzone--dragging,
body.fc-page-dragover .fc-dropzone {
  border-color: var(--fc-primary);
  background: color-mix(in srgb, var(--fc-primary-container) 12%, var(--fc-base));
  transform: scale(1.005);
}

@media (prefers-reduced-motion: reduce) {
  .fc-dropzone--dragging,
  body.fc-page-dragover .fc-dropzone {
    transform: none;
  }
}

.fc-dropzone--disabled {
  cursor: not-allowed;
  opacity: 0.45;
}

.fc-dropzone__icon {
  /* why: icon sits above the label to anchor the visual centre of the
     drop zone and make the affordance immediately legible. Dim colour
     keeps it from competing with the label text. */
  display: block;
  color: var(--fc-on-surface-dim);
  margin-bottom: 0.6rem;
  line-height: 0;
}

.fc-dropzone__icon svg {
  width: 2rem;
  height: 2rem;
}

.fc-dropzone__label {
  font-size: 1.05rem;
  font-weight: 700;
  margin: 0;
  color: var(--fc-on-surface);
  letter-spacing: -0.01em;
}

.fc-dropzone__hint {
  color: var(--fc-on-surface-variant);
  margin: 0;
  font-size: 0.85rem;
}

/* -- Controls (sidebar layout) ------------------------------------------ */

/* The controls panel lives inside the sidebar. Its layout is columnar
   (one control per row) so it fits the 256 px column width. */
.fc-controls {
  display: flex;
  flex-direction: column;
  padding: 0.5rem 0;
}

.fc-controls--disabled {
  opacity: 0.45;
  pointer-events: none;
}

.fc-controls__field {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 0.85rem 1.25rem;
  border-bottom: 1px solid var(--fc-outline-variant);
}

.fc-controls__field--group {
  border: none;   /* remove fieldset browser default */
  margin: 0;
  padding: 0.85rem 1.25rem;
  border-bottom: 1px solid var(--fc-outline-variant);
}

/* Legend / label: small section header for each control group. */
.fc-controls__field > label,
.fc-controls__field > legend,
.fc-controls__legend {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--fc-on-surface-variant);
  padding: 0;
  margin-bottom: 0.5rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* Icon before legend. */
.fc-controls__icon {
  display: inline-flex;
  align-items: center;
  color: var(--fc-primary);
  flex-shrink: 0;
}

.fc-controls__slider {
  width: 100%;
  height: 4px;
  accent-color: var(--fc-primary);
  cursor: pointer;
}

.fc-controls__readout {
  font-variant-numeric: tabular-nums;
  color: var(--fc-on-surface-variant);
  font-size: 0.75rem;
  text-align: right;
}

/* Blend mode select. */
.fc-controls__select {
  width: 100%;
  font: inherit;
  font-size: 0.8rem;
  background: var(--fc-surface-high);
  color: var(--fc-on-surface);
  border: 1px solid var(--fc-outline-variant);
  border-radius: var(--fc-radius-sm);
  padding: 0.35rem 0.55rem;
  cursor: pointer;
  accent-color: var(--fc-primary);
}

.fc-controls__select:focus {
  outline: 2px solid var(--fc-primary);
  outline-offset: 1px;
}

/* Overlay toggles — removed; visualizations now appear as static report sections. */

/*
 * JS tooltip system — was used by overlay checkboxes (removed).
 * Canvas hover tooltip (.fc-canvas-tooltip) is still active — kept below.
 */

/* Canvas hover tooltip — fixation sequence markers.
 *
 * Fixed-position pill that follows the cursor while hovering over a
 * numbered fixation circle on the composite canvas. Kept separate from
 * .fc-tooltip (which is absolutely-positioned relative to a parent) so
 * the two systems don't interfere. */
.fc-canvas-tooltip {
  position: fixed;
  pointer-events: none;
  background: var(--fc-surface-highest);
  color: var(--fc-on-surface);
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.3;
  padding: 0.3rem 0.6rem;
  border-radius: var(--fc-radius-sm);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.45);
  white-space: nowrap;
  opacity: 0;
  transform: translateY(4px);
  transition:
    opacity var(--fc-dur-fast) var(--fc-ease),
    transform var(--fc-dur-fast) var(--fc-ease);
  z-index: 300;
}

.fc-canvas-tooltip--visible {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .fc-canvas-tooltip {
    transition: opacity var(--fc-dur-fast) var(--fc-ease);
    transform: none;
  }
}

/* Export / download button — full-width CTA in the sidebar. */
.fc-controls__download {
  margin: 0.75rem 1.25rem;
  width: calc(100% - 2.5rem);
  font: inherit;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 0.7rem 1rem;
  background: var(--fc-primary-container);
  color: #ffffff;
  border: none;
  border-radius: var(--fc-radius-sm);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  transition: filter var(--fc-dur-fast) var(--fc-ease);
}

.fc-controls__download:hover:not(:disabled) {
  filter: brightness(1.15);
}

.fc-controls__download:disabled {
  cursor: not-allowed;
  opacity: 0.4;
  filter: none;
}

/* -- Output area --------------------------------------------------------- */

.fc-output {
  background: var(--fc-base);
  border-radius: var(--fc-radius);
  padding: 1.5rem;
  min-height: 240px;
  box-shadow: var(--fc-shadow-ambient);
  /* Needed so the waiting overlay can be positioned absolutely within. */
  position: relative;
}

.fc-output:focus-visible {
  outline: 3px solid var(--fc-focus);
  outline-offset: 3px;
}

.fc-output__canvas-wrap {
  width: 100%;
  /* Pointer cursor signals that clicking cycles through duration results. */
  cursor: pointer;
}

/*
 * Waiting overlay — shown via `.fc-output--waiting` on the parent section
 * while the user-selected duration is still loading in the background.
 * Sits as a sibling of the canvas-wrap so renderOutputView's
 * `textContent = ''` pass cannot delete it.
 */

.fc-output__waiting-overlay {
  display: none;
  position: absolute;
  inset: 0;
  background: rgba(7, 14, 29, 0.75);
  border-radius: var(--fc-radius);
  align-items: center;
  justify-content: center;
  z-index: 10;
}

.fc-output--waiting .fc-output__waiting-overlay {
  display: flex;
}

.fc-output__waiting-spinner {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 3px solid color-mix(in srgb, var(--fc-primary) 25%, transparent);
  border-top-color: var(--fc-primary);
  animation: fc-spin 0.8s linear infinite;
}

.fc-output__caption {
  margin: 0.75rem 0 0;
  color: var(--fc-on-surface-variant);
  font-size: 0.85rem;
  line-height: 1.4;
}

.fc-output__canvas-wrap canvas {
  display: block;
  max-width: 100%;
  height: auto;
  border-radius: var(--fc-radius-sm);
}

.fc-output__canvas-wrap--sidebyside {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;
}

@media (min-width: 720px) {
  .fc-output__canvas-wrap--sidebyside {
    grid-template-columns: 1fr 1fr;
  }
}

/* -- Mobile guard -------------------------------------------------------- */

.fc-mobile-guard {
  max-width: 480px;
  margin: 6rem auto 2rem;
  padding: 1.5rem;
  background: var(--fc-surface-mid);
  border: 1px solid var(--fc-outline-variant);
  border-radius: var(--fc-radius);
  text-align: center;
  color: var(--fc-on-surface);
}

.fc-mobile-guard__actions {
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--fc-outline-variant);
}

.fc-mobile-guard__caveat {
  margin: 0 0 0.75rem;
  color: var(--fc-on-surface-variant);
  font-size: 0.85rem;
}

.fc-mobile-guard__proceed {
  background: transparent;
  color: var(--fc-on-surface-variant);
  border: 1px solid var(--fc-outline);
  border-radius: var(--fc-radius-sm);
  padding: 0.5rem 1rem;
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
  transition: border-color var(--fc-dur-fast) var(--fc-ease),
              color var(--fc-dur-fast) var(--fc-ease);
}

.fc-mobile-guard__proceed:hover,
.fc-mobile-guard__proceed:focus-visible {
  border-color: var(--fc-primary);
  color: var(--fc-primary);
}

.fc-mobile-guard__proceed:focus-visible {
  outline: 3px solid var(--fc-focus);
  outline-offset: 3px;
}

/* -- Busy overlay -------------------------------------------------------- */
/*
 * Full-workspace overlay shown while a model load or inference run is
 * in progress. Sits at z-index 95 — above the sidebar (90) so it
 * covers the content area, but below the topnav (100) which remains
 * visible. Uses visibility rather than `hidden` so the 200 ms
 * fade-in/out transition fires correctly.
 */
.fc-busy-overlay {
  position: fixed;
  top: var(--fc-topnav-h);
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 95;
  /* --fc-base (#070e1d) at 90% — dark enough to read the spinner,
     transparent enough to hint at the page beneath. */
  background: rgba(7, 14, 29, 0.90);
  backdrop-filter: blur(6px);
  display: flex;
  align-items: center;
  justify-content: center;

  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  /* Fade out: opacity over 200ms, then hide visibility with 200ms delay. */
  transition: opacity 200ms ease, visibility 0ms linear 200ms;
}

.fc-busy-overlay--active {
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
  /* Fade in: show visibility immediately, then opacity over 200ms. */
  transition: opacity 200ms ease, visibility 0ms linear 0ms;
}

.fc-busy-overlay__card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.25rem;
}

.fc-busy-overlay__label {
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--fc-on-surface);
  letter-spacing: -0.01em;
  margin: 0;
}

/*
 * Slow-load hint — fades in (via the [hidden] removal in main.js) after
 * FC_SLOW_LOAD_HINT_MS so users on a first-visit/slow-network download
 * get an explanation rather than a silent wait. Constrained width keeps
 * it from sprawling on wide viewports.
 */
.fc-busy-overlay__hint {
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--fc-on-surface-dim);
  max-width: 32rem;
  margin: 0;
  text-align: center;
  /* Reveal animation. The element starts hidden via the `hidden`
     attribute, which display:none-s it; main.js removes the attribute
     when the timer fires, and the opacity transition takes over. */
  opacity: 0;
  transition: opacity 400ms ease;
}

.fc-busy-overlay__hint:not([hidden]) {
  opacity: 1;
}

.fc-busy-overlay__hint a {
  color: var(--fc-primary);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.fc-busy-overlay__hint a:hover,
.fc-busy-overlay__hint a:focus-visible {
  text-decoration-thickness: 2px;
}

/* -- Responsive: narrow viewport (< 900 px) ------------------------------ */
/*
 * Tighten horizontal padding on narrower viewports and hide the
 * topnav link list (navigation is available via in-page anchors and
 * the bottom toolbar).
 */
@media (max-width: 899px) {
  .fc-main {
    padding-left: 1.25rem;
    padding-right: 1.25rem;
  }

  .fc-topnav__links {
    display: none;
  }
}

/* -- Empty-state intro (pre-inference, single-column) --------------------- */

.fc-intro__text {
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--fc-on-surface-variant);
}

.fc-intro__tips {
  margin: 0;
  padding-left: 1.25rem;
  font-size: 0.8rem;
  color: var(--fc-on-surface-variant);
  line-height: 1.6;
}

.fc-intro__tips li + li {
  margin-top: 0.15rem;
}

/* -- Persistent bias disclaimer (between intro and dropzone) -------------- */
/*
 * Lives outside #fc-intro so it stays visible after showControls() hides
 * the intro. Reminds users that heatmaps are estimates, not measurements.
 */

.fc-disclaimer {
  margin: 0 0 1rem;
  font-size: 0.75rem;
  color: var(--fc-on-surface-variant);
  line-height: 1.5;
  max-width: 65ch;
}

/* -- Bottom toolbar ------------------------------------------------------- */
/*
 * Now used only as a loading indicator dock. Shown by showBgProgress() and
 * hidden by hideBgProgress() in main.js; collapsed the rest of the time.
 */
.fc-toolbar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 90;
  background: var(--fc-surface-low);
  border-top: 1px solid var(--fc-outline-variant);
  box-shadow: 0 -2px 12px rgba(7, 14, 29, 0.3);
}

/* -- Inline canvas controls ---------------------------------------------- */
/*
 * View-mode picker + opacity slider + download button rendered directly
 * below the hero canvas. Using a horizontal pill/row so the controls feel
 * attached to the image they govern rather than floating in a distant toolbar.
 */

.fc-canvas-controls-wrap .fc-controls {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  flex-wrap: wrap;
  padding: 0;
  margin-top: 0.75rem;
  background: var(--fc-surface-low);
  border: 1px solid var(--fc-outline-variant);
  border-radius: var(--fc-radius-sm);
  overflow: hidden;
}

.fc-canvas-controls-wrap .fc-controls__field,
.fc-canvas-controls-wrap .fc-controls__field--group {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0.5rem 0.9rem;
  border-bottom: none;
  border-right: 1px solid var(--fc-outline-variant);
  margin: 0;
  gap: 0.15rem;
  white-space: nowrap;
}

.fc-canvas-controls-wrap .fc-controls__field > label,
.fc-canvas-controls-wrap .fc-controls__field > legend,
.fc-canvas-controls-wrap .fc-controls__legend {
  font-size: 0.65rem;
  font-weight: 700;
  color: var(--fc-on-surface-variant);
  padding: 0;
  margin-bottom: 0.1rem;
  display: block;
  float: none;
}

.fc-canvas-controls-wrap .fc-controls__field--opacity {
  min-width: 160px;
}

.fc-canvas-controls-wrap .fc-controls__slider {
  width: 100%;
}

/* Download button: pushed to the trailing end of the controls row */
.fc-canvas-controls-wrap .fc-controls__download {
  margin: 0.4rem 0.75rem 0.4rem auto;
  width: auto;
  align-self: center;
  flex-shrink: 0;
}

/* -- Reduced motion ------------------------------------------------------ */
/*
 * Zeroing duration variables collapses every transition above without
 * touching the rule that sets it. The explicit overrides below handle
 * animation keyframes that duration-zeroing alone does not suppress.
 */
@media (prefers-reduced-motion: reduce) {
  :root {
    --fc-dur-fast: 0ms;
    --fc-dur-med:  0ms;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  .fc-status__progress:not([value]) {
    animation: none;
    background: var(--fc-outline-variant);
  }

  .fc-status__indicator--spin {
    animation: none;
    border-top-color: transparent;
    border-color: var(--fc-primary);
  }

  /* Spinner frozen at rest — show as a solid ring rather than a
     mid-spin arc, which looks broken. */
  .fc-busy-overlay__spinner {
    animation: none;
    border-color: var(--fc-primary);
  }

  /* Same treatment for the output-panel waiting spinner. */
  .fc-output__waiting-spinner {
    animation: none;
    border-color: var(--fc-primary);
  }
}

/* ==========================================================================
   Analysis Report section
   Appears below the interactive heatmap canvas after inference completes.
   The report presents findings in narrative order: primary finding, duration
   comparison strip, and methodology note.
   ========================================================================== */

.fc-report {
  border-top: 2px solid var(--fc-outline-variant);
  padding-top: 2.5rem;
}

/* Report top heading */
.fc-report__header {
  margin-bottom: 2rem;
}

.fc-report__heading {
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--fc-on-surface);
  letter-spacing: -0.01em;
  margin: 0;
}

/* Shared section wrapper */
.fc-report__section {
  padding: 2rem 0;
  border-top: 1px solid var(--fc-outline-variant);
}

.fc-report__section-heading {
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--fc-on-surface);
  margin: 0 0 1rem;
}

/* --------------------------------------------------------------------------
   Section 1 — Primary finding (hero + findings panel)
   Two-column on wide screens; stacks on narrow.
   -------------------------------------------------------------------------- */

.fc-report__section--primary {
  display: grid;
  grid-template-columns: minmax(0, 55%) minmax(0, 45%);
  gap: 2rem;
  align-items: start;
}

/* Duration tab bar spans both grid columns, sitting above hero + findings */
.fc-report__hero-tabs {
  grid-column: 1 / -1;
  display: flex;
  gap: 0.375rem;
  flex-wrap: wrap;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--fc-outline-variant);
  margin-bottom: 0.5rem;
}

.fc-report__hero-tab {
  padding: 0.45rem 1rem;
  border-radius: var(--fc-radius-sm);
  border: 1px solid var(--fc-outline-variant);
  background: var(--fc-surface-container);
  color: var(--fc-on-surface-variant);
  font-size: 0.85rem;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
  line-height: 1.4;
}

.fc-report__hero-tab[aria-selected="true"] {
  background: var(--fc-primary);
  color: var(--fc-on-primary);
  border-color: var(--fc-primary);
}

.fc-report__hero-tab[aria-disabled="true"] {
  opacity: 0.45;
  cursor: default;
}

.fc-report__hero-tab:not([aria-disabled="true"]):not([aria-selected="true"]):hover {
  background: var(--fc-surface-container-high);
  color: var(--fc-on-surface);
}

.fc-report__hero-tab:focus-visible {
  outline: 2px solid var(--fc-primary);
  outline-offset: 2px;
}

/* Hero figure */
.fc-report__hero {
  margin: 0;
}

.fc-report__hero-canvas canvas {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 4px;
}

/* Findings panel */
.fc-report__findings {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.fc-report__headline {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--fc-on-surface);
  line-height: 1.4;
  margin: 0;
}

.fc-report__fixation-note {
  font-size: 0.9rem;
  color: var(--fc-on-surface-variant);
  margin: 0;
  line-height: 1.5;
}

.fc-report__source-label {
  font-size: 0.8rem;
  color: var(--fc-on-surface-variant);
  margin: 0;
}

/* Rule-of-thirds grid */
.fc-report__rot-wrap {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.fc-report__rot-label {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--fc-on-surface-variant);
  margin: 0;
}

.fc-report__rot-hint {
  font-size: 0.72rem;
  color: var(--fc-on-surface-dim);
  margin: 0;
  line-height: 1.4;
}

.fc-report__rot-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
  max-width: 200px;
}

.fc-report__rot-cell {
  /* Background is set inline by renderRotGrid on the heat scale;
     fallback here in case JS hasn't run yet. */
  background: var(--fc-surface-container);
  color: var(--fc-on-surface-variant);
  font-size: 0.8rem;
  font-weight: 600;
  text-align: center;
  padding: 0.4rem 0.25rem;
  border-radius: 2px;
  /* why: min-height keeps cells square-ish regardless of percentage string length. */
  min-height: 2.4rem;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--fc-dur-fast);
}

/* Max-attention cell: bold weight; background/color come from inline heat scale.
   aria-label on each cell conveys the maximum distinction to screen readers. */
.fc-report__rot-cell--max {
  font-weight: 700;
}

/* --------------------------------------------------------------------------
   Section 2 — Duration comparison strip
   -------------------------------------------------------------------------- */

.fc-report__section--durations {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.fc-report__duration-note {
  font-size: 0.9rem;
  color: var(--fc-on-surface-variant);
  margin: 0;
  line-height: 1.5;
  max-width: 55ch;
}

.fc-report__strip {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.5rem;
}

.fc-report__dur-item {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
  background: var(--fc-surface-container);
  border-radius: var(--fc-radius-sm, 6px);
  overflow: hidden;
}

.fc-report__dur-canvas {
  /* Fixed aspect ratio placeholder before the canvas arrives. */
  aspect-ratio: 16 / 9;
  background: var(--fc-surface-high);
  overflow: hidden;
  position: relative;
}

.fc-report__dur-canvas canvas {
  display: block;
  width: 100%;
  height: auto;
}

/* Pending / loading placeholder — fills the aspect-ratio box. */
.fc-report__dur-placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Animated pulse for the loading state. */
.fc-report__dur-canvas[aria-busy="true"] .fc-report__dur-placeholder {
  animation: fc-report-pulse 1.4s ease-in-out infinite;
}

@keyframes fc-report-pulse {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.4; }
}

.fc-report__dur-placeholder--failed::after {
  content: 'Unavailable';
  font-size: 0.7rem;
  color: var(--fc-on-surface-dim);
}

.fc-report__dur-label {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--fc-on-surface-variant);
  padding: 0.5rem 0.75rem;
}

/* --------------------------------------------------------------------------
   Sections 3 & 4 — Overlay strips (fixation sequence, attention zones)
   -------------------------------------------------------------------------- */

.fc-report__section--overlay {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* Short descriptive paragraph under each overlay section heading. */
.fc-report__overlay-note {
  font-size: 0.8rem;
  line-height: 1.55;
  color: var(--fc-on-surface-variant);
  max-width: 60ch;
  margin: 0;
}

/* --------------------------------------------------------------------------
   Section 5 — Centroid trajectory (cross-duration)
   -------------------------------------------------------------------------- */

.fc-report__section--trajectory {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* Single centred canvas container for the trajectory thumbnail. */
.fc-report__trajectory-wrap {
  display: flex;
  justify-content: center;
}

.fc-report__trajectory-wrap canvas {
  max-width: 100%;
  height: auto;
  border-radius: var(--fc-radius-sm);
  display: block;
}

/* --------------------------------------------------------------------------
   Section 6 — About this analysis (description + model credits)
   -------------------------------------------------------------------------- */

.fc-report__section--methodology {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.fc-report__method-body {
  font-size: 0.8rem;
  color: var(--fc-on-surface-variant);
  line-height: 1.6;
  margin: 0;
  max-width: 65ch;
}

/* Model identifier line — shown above the full attribution paragraph. */
.fc-report__credits-model {
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  color: var(--fc-on-surface-variant);
  margin: 0;
}

/* Attribution paragraph: architecture, training, inference. */
.fc-report__credits {
  font-size: 0.75rem;
  color: var(--fc-on-surface-variant);
  line-height: 1.6;
  margin: 0;
  max-width: 65ch;
}

.fc-report__credits a {
  color: var(--fc-primary);
  text-decoration: none;
}

.fc-report__credits a:hover {
  text-decoration: underline;
}

.fc-report__method-links {
  display: flex;
  gap: 1.25rem;
  flex-wrap: wrap;
}

.fc-report__method-link {
  font-size: 0.75rem;
  color: var(--fc-primary);
  text-decoration: none;
}

.fc-report__method-link:hover,
.fc-report__method-link:focus-visible {
  text-decoration: underline;
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   Responsive: below the sidebar breakpoint, stack the primary section
   -------------------------------------------------------------------------- */

@media (max-width: 860px) {
  .fc-report__section--primary {
    grid-template-columns: 1fr;
  }
}

/* Reduced motion: disable the placeholder pulse. */
@media (prefers-reduced-motion: reduce) {
  .fc-report__dur-canvas[aria-busy="true"] .fc-report__dur-placeholder {
    animation: none;
    opacity: 0.6;
  }
}
