/* ASP Consulting — spacing, radius, borders, elevation, motion */
:root {
  /* Spacing — 4px base, generous editorial whitespace */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;

  /* Radius — the logo mark's soft corner is the reference */
  --radius-sm: 4px;    /* inputs, tags */
  --radius-md: 8px;    /* buttons, small cards */
  --radius-lg: 16px;   /* cards */
  --radius-xl: 24px;   /* feature cards, social frames */
  --radius-pill: 999px;

  /* Content shell — how wide the screen area beside the 216px rail may grow.
     Was hardcoded at 1440px, which left a 1920 display ~290px of unused page
     and squeezed the wide screens (the timesheet's seven day columns, Projects,
     Invoices, Bank) while doing nothing for reading width — running text caps
     itself at 78–104ch inside the views (Karan 25/08). 1680 uses a 1920 screen
     properly and still holds a sensible line on an ultrawide. */
  --content-max: 1760px;   /* §4: 1440 → 1760 for the polish pass */

  /* Borders */
  --border-w: 1px;
  --border-w-rule: 1px;

  /* Elevation — flat by default; one soft shadow for floating surfaces only */
  --shadow-none: none;
  --shadow-card: 0 1px 3px rgba(12, 17, 57, 0.08); /* was referenced but undefined (Karan 16/07) */
  --shadow-float: 0 8px 32px rgba(12, 17, 57, 0.12);
  --shadow-dialog: 0 16px 56px rgba(12, 17, 57, 0.20);

  /* Motion — quick, precise, no bounce */
  --ease-out: cubic-bezier(0.2, 0.6, 0.2, 1); /* @kind other */
  /* The one spring in the system: the phone's tab press and the pill that
     scales in under it (design_handoff_track_polish §13). Overshoots by design
     — a 66px bar floating over content needs the press to be felt, not seen.
     Nothing else may use it. */
  --ease-spring: cubic-bezier(.3, 1.6, .6, 1); /* @kind other */
  --dur-fast: 120ms; /* @kind other */
  --dur-base: 200ms; /* @kind other */
  --dur-slow: 320ms; /* @kind other */

  /* Benchmark motion (HANDOFF §3). Everything on --ease-out; no bounce, no
     parallax. Durations and delays are the design's exact table so the status
     card "fills left to right and stops dead at the break" — that stagger is
     the point of it. --bm-stagger is the per-node step for chain nodes and
     connectors. */
  --bm-dur-scrim: 200ms;   /* overlay scrim fade */
  --bm-dur-rise: 320ms;    /* anchor figure, figures card, brief */
  --bm-dur-figure: 300ms;  /* the 38px figures */
  --bm-dur-pop: 260ms;     /* chain nodes */
  --bm-dur-draw: 320ms;    /* chain connectors */
  --bm-dur-bar: 380ms;     /* budget / progress bars (340–400ms) */
  --bm-dur-shimmer: 1400ms;
  --bm-delay-card: 80ms;   /* figures card */
  --bm-delay-brief: 140ms; /* brief block */
  --bm-delay-figures: 200ms;
  --bm-delay-table: 160ms;  /* the register block */
  --bm-delay-nodes: 260ms;  /* + --bm-stagger per node */
  --bm-delay-connectors: 320ms; /* + --bm-stagger per node */
  --bm-delay-bar: 420ms;
  --bm-stagger: 80ms;
}

/* Dark (06/10/2026): no shadows on cards — the surface colour and hairlines
   separate them. Floating layers keep a shadow, in black rather than navy. */
[data-theme="dark"] {
  --shadow-card: none;
  --shadow-float: 0 8px 32px rgba(0, 0, 0, 0.45);
  --shadow-dialog: 0 16px 56px rgba(0, 0, 0, 0.55);
}

/* Benchmark keyframes. Named bm-* so they never collide with the legacy
   about-in / skel-sweep / whatsnew-fade animations still in styles.css. */
@keyframes bm-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes bm-pop  { from { opacity: 0; transform: scale(0.35); } to { opacity: 1; transform: scale(1); } }
@keyframes bm-draw { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes bm-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes bm-shimmer { from { background-position: -180% 0; } to { background-position: 180% 0; } }
/* A bar grown from its baseline, not faded in. transform-origin is set where it
   is used, because an SVG rect's origin is the viewBox unless it is told. */
@keyframes bm-grow { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes bm-grow-x { from { transform: scaleX(0); } to { transform: scaleX(1); } }
/* The portfolio ring: each segment drawn round rather than appearing (§11). The
   element sets --dash to its own length. */
@keyframes bm-ring { from { stroke-dashoffset: var(--dash); } to { stroke-dashoffset: 0; } }
/* The node you are on breathes — 3px of halo to 6px and back, forever. It is
   the one infinite animation in the app, so it is linear and slow enough to
   read as presence rather than as something demanding attention. */
@keyframes bm-halo {
  0%, 100% { box-shadow: 0 0 0 3px var(--halo); }
  50% { box-shadow: 0 0 0 6px var(--halo); }
}
/* THE ROUTE CHANGE (§5). Two identical keyframes under different names: the
   browser will not re-run an animation that already ran, so app.js alternates
   between them and every navigation rises again. */
@keyframes bm-view-rise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes bm-view-rise2 { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }

/* Reusable entrance utilities. Compose delays inline where a screen needs the
   staggered reveal (anchor → card → brief → figures → chain). */
.bm-in-rise   { animation: bm-rise var(--bm-dur-rise) var(--ease-out) both; }
.bm-in-figure { animation: bm-rise var(--bm-dur-figure) var(--ease-out) both; }
.bm-in-pop    { animation: bm-pop var(--bm-dur-pop) var(--ease-out) both; }
.bm-in-draw   { transform-origin: left center; animation: bm-draw var(--bm-dur-draw) var(--ease-out) both; }
.bm-in-fade   { animation: bm-fade var(--bm-dur-scrim) var(--ease-out) both; }
/* The table block, last in the stagger (§5): 320ms at 160 — after the card
   at 80 and with the brief at 140, so the screen resolves top to bottom. */
.bm-in-table  { animation: bm-rise var(--bm-dur-rise) var(--ease-out) var(--bm-delay-table) both; }

/* Respect the OS setting — no motion means the reveal is instant, not absent.
   Covers both the entrance utilities and the §7.2 components, which apply the
   keyframes directly. */
@media (prefers-reduced-motion: reduce) {
  .bm-in-rise, .bm-in-figure, .bm-in-pop, .bm-in-draw, .bm-in-fade,
  .bm-open, .bm-card, .bm-cfig, .bm-node, .bm-conn, .bm-brief, .bm-in-table,
  .view, [style*="bm-grow"], [style*="bm-ring"], .bm-node.current {
    animation: none !important;
  }
}
