/* Animated hero demo: the three product screens (input form, analysis
   pipeline, risk report) rendered as live HTML instead of a static PNG, so the
   page can "type" a sample case through them. Loaded only by index.html.
   All class names are prefixed cad- (Credit Atlas demo) to stay out of the
   way of the page styles.

   Layout: the three panels are NOT a filmstrip. They share one 3D stage in the
   right-hand hero column, absolutely positioned on the same centre point and
   separated on Z. Exactly one panel sits at translateZ(0) rotateY(0) rotateX(0)
   -- that state resolves to a plain 2D matrix at scale 1.000, which is what
   keeps the 11-12px panel type at native subpixel rasterisation. Work still to
   come fans up-and-back-right (the queue); work already done fans
   down-and-back-left (the archive).

   All of it is driven by the class toggles hero-demo.js already performs:
   .is-active = front slot, .is-done = archive, neither = queue. The general
   sibling combinator resolves fan depth, so the queue self-collapses as panels
   retire and no JS bookkeeping is needed. */

/* Two-column hero ---------------------------------------------------------- */
.hero-split {
    display: grid;
    grid-template-columns: minmax(400px, 0.86fr) minmax(0, 1.14fr);
    gap: clamp(28px, 4vw, 56px);
    align-items: center;
    padding: 8px 0 40px;
}
.hero-split > * {
    min-width: 0;
}

/* Undo the centred hero, inside the split only. */
.hero-split .hero-bold {
    max-width: none;
    margin: 0;
    padding: 0;
    text-align: left;
    container-type: inline-size;
}
/* Type scale tracks the COLUMN, not the viewport: at 52px the Slovak and
   Slovenian headlines wrap to 3-4 lines and unbalance the split. */
.hero-split .hero-bold h1 {
    font-size: clamp(30px, 3.05vw, 46px);
    margin-bottom: var(--spacing-sm);
}
@supports (container-type: inline-size) {
    .hero-split .hero-bold h1 {
        font-size: clamp(30px, 9.2cqi, 46px);
    }
}
/* The standing line wraps to two lines in the narrower column, so pin the dot
   to the first line instead of letting it centre against the whole block.
   Centre it on the x-height, where a typographic bullet sits: in DM Sans at
   line-height 1.6 that is 0.887em below the line top; subtract half the dot. */
.hero-split .hero-tagline {
    align-items: flex-start;
    font-size: 22px;
    margin-bottom: var(--spacing-sm);
}
.hero-split .hero-tagline-dot {
    margin-top: calc(0.887em - 5px);
}
.hero-split .hero-bold .hero-lead {
    margin: 0;
    max-width: 46ch;
    font-size: 17px;
}
.hero-split .hero-bold .hero-buttons {
    justify-content: flex-start;
    margin: 32px 0 0;
}
.hero-split .checklist {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: 10px;
    margin: 28px 0 0;
    padding: 0;
}

.cad-demo {
    --cad-green: #1A5C3A;
    --cad-green-deep: #0B2618;
    --cad-ink: #191919;
    --cad-muted: #6B716D;
    --cad-line: rgba(25, 25, 25, 0.08);
    --cad-ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1);
    position: relative;
    margin: 0;
    max-width: none;
    padding: 0;
    isolation: isolate;
}

/* Ambient light behind the glass so the blur has something to catch. The
   wrapper clips the blobs to the demo box so they never widen the page.
   It stays a SIBLING of .cad-stage -- it carries overflow:hidden, which would
   flatten the 3D context if it ever wrapped the stage. */
.cad-glows {
    position: absolute;
    inset: 0;
    overflow: hidden;
    border-radius: 24px;
    z-index: 0;
    pointer-events: none;
}
.cad-glow {
    position: absolute;
    border-radius: 50%;
    filter: blur(70px);
    pointer-events: none;
    z-index: 0;
    opacity: 0.9;
}
.cad-glow-a {
    width: 520px;
    height: 420px;
    left: -6%;
    top: -10%;
    background: radial-gradient(circle at 40% 40%, rgba(26, 92, 58, 0.22), rgba(26, 92, 58, 0) 70%);
    animation: cad-drift-a 18s ease-in-out infinite alternate;
}
.cad-glow-b {
    width: 560px;
    height: 460px;
    right: -8%;
    bottom: -12%;
    background: radial-gradient(circle at 60% 60%, rgba(196, 184, 150, 0.35), rgba(196, 184, 150, 0) 70%);
    animation: cad-drift-b 22s ease-in-out infinite alternate;
}
.cad-glow-c {
    width: 380px;
    height: 380px;
    left: 42%;
    top: 30%;
    background: radial-gradient(circle, rgba(26, 92, 58, 0.14), rgba(26, 92, 58, 0) 70%);
    animation: cad-drift-a 26s ease-in-out infinite alternate-reverse;
}
@keyframes cad-drift-a {
    from { transform: translate3d(0, 0, 0) scale(1); }
    to   { transform: translate3d(40px, 30px, 0) scale(1.08); }
}
@keyframes cad-drift-b {
    from { transform: translate3d(0, 0, 0) scale(1.05); }
    to   { transform: translate3d(-50px, -20px, 0) scale(0.96); }
}

/* The 3D stage ------------------------------------------------------------- */
.cad-stage {
    /* --cad-deck-h is a MIN-HEIGHT floor, never a clip. Natural panel heights
       at 440px wide: form 502 / pipeline 423 / report 541. */
    --cad-panel-w: 440px;
    --cad-deck-h: 560px;
    --fan: 1;    /* lateral spread + yaw multiplier; 0 = pure vertical deck */
    --rise: 1;   /* vertical spread multiplier */
    position: relative;
    z-index: 1;
    display: block;
    width: 100%;
    max-width: 660px;
    height: 660px;
    margin: 0 auto;
    perspective: 1500px;
    /* Pointer parallax moves the CAMERA, not the cards: a plane at z=0 is
       invariant under a change of vanishing point, so the readable front card
       never moves or resamples while the deck re-projects around it. */
    perspective-origin: calc(54% + var(--px, 0) * 9%) calc(44% + var(--py, 0) * 6%);
    transform-style: preserve-3d;
    contain: layout style; /* NOT paint -- that would force transform-style: flat */
    transition: perspective-origin 260ms var(--cad-ease-out-quint);
}

/* Panels ------------------------------------------------------------------- */
.cad-panel {
    position: absolute;
    left: 50%;
    top: 50%;
    width: var(--cad-panel-w);
    min-height: var(--cad-deck-h);
    display: flex;
    flex-direction: column;
    --tx: 0px; --ty: 0px; --tz: 0px; --ry: 0deg; --rx: 0deg;
    /* One variable-driven stack: slots are variable SETS, never new transform
       strings, so the function list is identical in every state and the browser
       interpolates component-wise instead of decomposing matrices. */
    transform:
        translate3d(calc(-50% + var(--tx) * var(--fan)),
                    calc(-50% + var(--ty) * var(--rise)),
                    var(--tz))
        rotateY(calc(var(--ry) * var(--fan)))
        rotateX(calc(var(--rx) * var(--fan)));
    opacity: var(--dim, 1);
    /* Glass on the front card only: three rotated backdrop-filter surfaces over
       three animating blur blobs is the main GPU cost and the main Safari
       mis-sampling risk. .90 -> .97 also stops the receded cards' 11px type
       reading straight through the front panel. */
    background: rgba(255, 255, 255, 0.90);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border: 1px solid rgba(255, 255, 255, 0.9);
    border-radius: 18px;
    padding: 22px 20px;
    box-shadow:
        0 12px 26px -14px rgba(11, 38, 24, 0.16),
        inset 0 1px 0 rgba(255, 255, 255, 0.75);
    /* No will-change: transitions auto-promote for their duration, and a
       permanent layer forces grayscale AA on the one panel anybody reads. */
    transition:
        transform 820ms cubic-bezier(0.4, 0, 0.2, 1),
        opacity 620ms ease,
        box-shadow 520ms ease,
        border-color 520ms ease,
        background-color 520ms ease;
    overflow: hidden;
    color: var(--cad-ink);
    text-align: left;
    font-size: 12px;
    line-height: 1.45;
}
.cad-panel::before {
    /* faint top highlight, gives the "glass edge" */
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0) 38%);
    pointer-events: none;
}

/* Aerial perspective, opacity-only. An animated filter: blur() would
   re-rasterise a 440x560 layer every frame; this is compositor-only and on a
   linen ground it reads as haze more convincingly than a Gaussian would. */
.cad-haze {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    z-index: 5;
    background: linear-gradient(180deg, rgba(236, 234, 229, 0.6), rgba(11, 38, 24, 0.3));
    opacity: var(--haze, 0);
    transition: opacity 820ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* Slot table. Every group is guarded by :not(), so the three states are
   mutually exclusive by non-matching and no rule ever has to out-specify
   another -- which is what makes the finale and the reset safe. */

/* QUEUE (no state class) -- fans up-and-back-right. */
.cad-demo:not(.is-complete):not(.is-resetting) .cad-panel:not(.is-active):not(.is-done) {
    --tx: 54px;  --ty: -46px;  --tz: -170px; --ry: -10deg; --rx: 2deg; --dim: 0.66; --haze: 0.62;
}
.cad-demo:not(.is-complete):not(.is-resetting) .cad-panel:not(.is-active):not(.is-done)
  ~ .cad-panel:not(.is-active):not(.is-done) {
    --tx: 110px; --ty: -94px;  --tz: -330px; --ry: -12deg; --rx: 3deg; --dim: 0.42; --haze: 0.80;
}
.cad-demo:not(.is-complete):not(.is-resetting) .cad-panel:not(.is-active):not(.is-done)
  ~ .cad-panel:not(.is-active):not(.is-done)
  ~ .cad-panel:not(.is-active):not(.is-done) {
    --tx: 152px; --ty: -134px; --tz: -470px; --ry: -13deg; --rx: 3deg; --dim: 0.24; --haze: 0.88;
}

/* ARCHIVE (.is-done) -- fans down-and-back-left; later-done sits nearer. */
.cad-demo:not(.is-complete):not(.is-resetting) .cad-panel.is-done {
    --tx: -122px; --ty: 96px; --tz: -320px; --ry: 12deg; --rx: -2deg;   --dim: 0.32; --haze: 0.82;
}
.cad-demo:not(.is-complete):not(.is-resetting) .cad-panel.is-done ~ .cad-panel.is-done {
    --tx: -58px;  --ty: 50px; --tz: -190px; --ry: 10deg; --rx: -1.5deg; --dim: 0.48; --haze: 0.64;
}

/* FRONT (.is-active) -- identity; the only card meant to be read. */
.cad-demo:not(.is-resetting) .cad-panel.is-active {
    --tx: 0px; --ty: 0px; --tz: 0px; --ry: 0deg; --rx: 0deg; --dim: 1; --haze: 0;
    /* Asymmetric easing: the front card lands first (quintic-out, no
       overshoot -- a spring reads as a toy on a bank-facing page) and the
       archive settles behind it, so the two motions never read as one slab. */
    transition-duration: 700ms;
    transition-timing-function: var(--cad-ease-out-quint);
}
.cad-demo:not(.is-resetting) .cad-panel.is-active,
.cad-demo.is-complete:not(.is-resetting) .cad-panel[data-panel="3"] {
    background: rgba(255, 255, 255, 0.97);
    -webkit-backdrop-filter: blur(18px) saturate(1.3);
    backdrop-filter: blur(18px) saturate(1.3);
    border-color: rgba(26, 92, 58, 0.35);
    box-shadow:
        0 40px 80px -20px rgba(11, 38, 24, 0.28),
        0 12px 28px -12px rgba(11, 38, 24, 0.18),
        0 0 0 1px rgba(26, 92, 58, 0.22),
        0 0 90px rgba(26, 92, 58, 0.14),
        inset 0 1px 0 rgba(255, 255, 255, 0.95);
}

/* Finale: sequence() sets P3 is-done and .is-complete in the same synchronous
   block, which would fling the finished report to the archive and leave the
   front slot empty for the 6s hold. Pin the deck instead.
   The :not(.is-resetting) is load-bearing: resetAll() only clears is-complete
   at the top of the NEXT sequence(), so for 500ms both classes are on the root
   and the finale would otherwise beat the reset. */
.cad-demo.is-complete:not(.is-resetting) .cad-panel[data-panel="3"] {
    --tx: 0px; --ty: 0px; --tz: 0px; --ry: 0deg; --rx: 0deg; --dim: 1; --haze: 0;
}
.cad-demo.is-complete:not(.is-resetting) .cad-panel[data-panel="2"] {
    --tx: -58px;  --ty: 50px; --tz: -190px; --ry: 10deg; --rx: -1.5deg; --dim: 0.48; --haze: 0.64;
}
.cad-demo.is-complete:not(.is-resetting) .cad-panel[data-panel="1"] {
    --tx: -122px; --ty: 96px; --tz: -320px; --ry: 12deg; --rx: -2deg;   --dim: 0.32; --haze: 0.82;
}

/* Shimmer sweep across the front card once the report is ready. */
.cad-panel::after {
    content: "";
    position: absolute;
    top: -30%;
    bottom: -30%;
    left: -60%;
    width: 45%;
    background: linear-gradient(105deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.75) 50%, rgba(255, 255, 255, 0) 100%);
    transform: skewX(-18deg);
    opacity: 0;
    pointer-events: none;
    z-index: 6;
}
.cad-demo.is-complete:not(.is-resetting) .cad-panel[data-panel="3"]::after {
    animation: cad-shimmer 1.4s ease-out 0.5s forwards;
}
@keyframes cad-shimmer {
    0%   { left: -60%; opacity: 0; }
    15%  { opacity: 1; }
    100% { left: 130%; opacity: 0; }
}

/* Reset between loops: the whole deck retreats and dissolves. JS waits 500ms
   after adding .is-resetting, so 420ms lands inside it. */
.cad-demo.is-resetting .cad-panel {
    --tz: -140px;
    --dim: 0;
    transition: transform 420ms cubic-bezier(0.4, 0, 1, 1), opacity 380ms ease;
}

.cad-panel h3 {
    font-size: 14px;
    font-weight: 700;
    letter-spacing: -0.01em;
    margin: 0 0 2px;
    color: var(--cad-ink);
}
.cad-panel p {
    margin: 0;
    color: var(--cad-muted);
    font-size: 11.5px;
}
.cad-panel-head {
    margin-bottom: 16px;
}

/* Uniform card height: every panel gets the same box, so the composition does
   not shrink and grow as the sequence advances. Distribute the slack instead
   of leaving it as dead space at the bottom. */
.cad-panel-form .cad-submit {
    margin-top: auto;
}
.cad-panel-process .cad-steps {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
}
.cad-report .cad-ready {
    margin-top: auto;
}

/* Panel 1: form -------------------------------------------------------------- */
.cad-field {
    margin-bottom: 11px;
}
.cad-field label {
    display: block;
    font-size: 11px;
    font-weight: 600;
    color: var(--cad-green);
    margin-bottom: 4px;
}
.cad-input {
    position: relative;
    display: flex;
    align-items: center;
    height: 30px;
    padding: 0 10px;
    border: 1px solid var(--cad-line);
    border-radius: 7px;
    background: rgba(255, 255, 255, 0.85);
    font-size: 12px;
    color: var(--cad-ink);
    transition: border-color 0.25s ease, box-shadow 0.25s ease, background-color 0.25s ease;
    white-space: nowrap;
    overflow: hidden;
}
.cad-input .cad-value {
    overflow: hidden;
    text-overflow: ellipsis;
}
.cad-input .cad-value:empty::before {
    content: attr(data-placeholder);
    color: #A3A7A4;
}
.cad-input.is-focus {
    border-color: var(--cad-green);
    box-shadow: 0 0 0 3px rgba(26, 92, 58, 0.14);
    background: #fff;
}
.cad-input.is-filled {
    border-color: rgba(26, 92, 58, 0.35);
}
.cad-caret {
    display: none;
    width: 1px;
    height: 14px;
    margin-left: 1px;
    background: var(--cad-ink);
    animation: cad-blink 1s steps(2, start) infinite;
}
.cad-input.is-focus .cad-caret {
    display: inline-block;
}
@keyframes cad-blink {
    to { visibility: hidden; }
}
.cad-select .cad-chevron {
    margin-left: auto;
    width: 12px;
    height: 12px;
    color: #8B908C;
    flex-shrink: 0;
    transition: transform 0.25s ease;
}
.cad-select.is-open .cad-chevron {
    transform: rotate(180deg);
}
.cad-submit {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    height: 34px;
    margin-top: 16px;
    border: 0;
    border-radius: 7px;
    background: var(--cad-green);
    color: #fff;
    font: inherit;
    font-size: 12.5px;
    font-weight: 600;
    box-shadow: 0 6px 16px rgba(26, 92, 58, 0.22);
    transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.25s ease;
    pointer-events: none;
}
.cad-submit.is-pressed {
    transform: scale(0.97);
    box-shadow: 0 2px 6px rgba(26, 92, 58, 0.2);
}
.cad-submit.is-busy {
    background: #2A6D4A;
}
.cad-submit .cad-spinner {
    display: none;
}
.cad-submit.is-busy .cad-spinner {
    display: inline-block;
}

/* Spinner shared by the submit button and the pipeline steps. */
.cad-spinner {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.35);
    border-top-color: #fff;
    animation: cad-spin 0.8s linear infinite;
    flex-shrink: 0;
}
@keyframes cad-spin {
    to { transform: rotate(360deg); }
}

/* Flow rail --------------------------------------------------------------- */
/* The two arrows live OUTSIDE the 3D stage. Inside transform-style:preserve-3d
   children are depth-sorted and z-index is not honoured, so a glyph animating
   through Z would sit behind the archive and queue cards for most of its
   flight. Flat rail beneath the deck instead; it also restores the explicit
   three-step story the deck otherwise carries only spatially.
   setArrow() indexes .cad-arrow inside #cad-demo, so it needs no change. */
.cad-flow {
    position: relative;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    margin-top: 8px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.cad-flow-step {
    color: #9AA39D;
    transition: color 0.45s ease, transform 0.45s var(--cad-ease-out-quint);
}
.cad-demo[data-act="1"] .cad-flow-step[data-step="1"],
.cad-demo[data-act="2"] .cad-flow-step[data-step="2"],
.cad-demo[data-act="3"] .cad-flow-step[data-step="3"] {
    color: var(--cad-green);
    transform: translateY(-1px);
}
.cad-arrow {
    width: 18px;
    height: 18px;
    color: #C9D3CC;
    flex-shrink: 0;
    transition: color 0.5s ease, filter 0.5s ease, transform 0.5s var(--cad-ease-out-quint);
}
.cad-arrow svg {
    width: 100%;
    height: 100%;
    display: block;
}
.cad-arrow.is-lit {
    color: var(--cad-green);
    filter: drop-shadow(0 0 8px rgba(26, 92, 58, 0.45));
    transform: translateX(2px);
}

/* Panel 2: pipeline -------------------------------------------------------- */
.cad-steps {
    list-style: none;
    margin: 0;
    padding: 0;
    position: relative;
}
.cad-steps::before {
    /* rail behind the step circles */
    content: "";
    position: absolute;
    left: 13px;
    top: 14px;
    bottom: 14px;
    width: 2px;
    background: rgba(25, 25, 25, 0.08);
}
.cad-rail-fill {
    /* filled part of the rail, grows as steps complete */
    position: absolute;
    left: 13px;
    top: 14px;
    width: 2px;
    height: 0;
    background: var(--cad-green);
    transition: height 0.5s ease;
}
.cad-step {
    position: relative;
    display: flex;
    gap: 12px;
    align-items: flex-start;
    padding: 0 0 12px;
}
.cad-step:last-child {
    padding-bottom: 0;
}
.cad-step-num {
    position: relative;
    z-index: 1;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #fff;
    border: 2px solid rgba(25, 25, 25, 0.12);
    color: #8B908C;
    font-size: 11px;
    font-weight: 700;
    flex-shrink: 0;
    transition: background-color 0.3s ease, border-color 0.3s ease, color 0.3s ease, box-shadow 0.3s ease;
}
.cad-step-num .cad-spinner,
.cad-step-num .cad-check {
    display: none;
}
.cad-step-num .cad-check {
    width: 14px;
    height: 14px;
}
.cad-step-body {
    flex: 1;
    min-width: 0;
    padding: 7px 10px;
    border: 1px solid transparent;
    border-radius: 9px;
    transition: background-color 0.3s ease, border-color 0.3s ease;
}
.cad-step-body h4 {
    margin: 0 0 1px;
    font-size: 12px;
    font-weight: 700;
    color: #8B908C;
    transition: color 0.3s ease;
}
.cad-step-body p {
    font-size: 11px;
    color: #9A9E9B;
    transition: color 0.3s ease;
}
.cad-step.is-running .cad-step-num {
    border-color: var(--cad-green);
    background: var(--cad-green);
    color: #fff;
    box-shadow: 0 0 0 4px rgba(26, 92, 58, 0.14), 0 0 18px rgba(26, 92, 58, 0.35);
}
.cad-step.is-running .cad-step-idx { display: none; }
.cad-step.is-running .cad-step-num .cad-spinner { display: inline-block; }
.cad-step.is-running .cad-step-body {
    background: rgba(26, 92, 58, 0.06);
    border-color: rgba(26, 92, 58, 0.18);
}
.cad-step.is-running .cad-step-body h4 { color: var(--cad-green); }
.cad-step.is-running .cad-step-body p { color: var(--cad-muted); }

.cad-step.is-done .cad-step-num {
    border-color: var(--cad-green);
    background: var(--cad-green);
    color: #fff;
}
.cad-step.is-done .cad-step-idx { display: none; }
.cad-step.is-done .cad-step-num .cad-check { display: block; }
.cad-step.is-done .cad-step-body h4 { color: var(--cad-ink); }
.cad-step.is-done .cad-step-body p { color: var(--cad-muted); }

/* Panel 3: report ----------------------------------------------------------- */
.cad-report-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 10px;
    padding-bottom: 12px;
    margin-bottom: 14px;
    border-bottom: 1px solid var(--cad-line);
}
.cad-overall {
    text-align: right;
    font-size: 11px;
    font-weight: 600;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
    white-space: nowrap;
}
.cad-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    background: #DFF1E6;
    color: var(--cad-green);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.02em;
    opacity: 0;
    transform: scale(0.85);
    transition: opacity 0.35s ease, transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.cad-report.is-scored .cad-badge {
    opacity: 1;
    transform: scale(1);
}
.cad-score-row {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 14px;
}
.cad-ring {
    position: relative;
    width: 88px;
    height: 88px;
    flex-shrink: 0;
}
.cad-ring svg {
    width: 100%;
    height: 100%;
    transform: rotate(-90deg);
    display: block;
}
.cad-ring-track {
    fill: none;
    stroke: rgba(25, 25, 25, 0.08);
    stroke-width: 9;
}
.cad-ring-fill {
    fill: none;
    stroke: var(--cad-green);
    stroke-width: 9;
    stroke-linecap: round;
    stroke-dasharray: 314.16;
    stroke-dashoffset: 314.16;
    transition: stroke-dashoffset 1.4s cubic-bezier(0.22, 1, 0.36, 1);
    filter: drop-shadow(0 0 6px rgba(26, 92, 58, 0.35));
}
.cad-ring-label {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    line-height: 1;
}
.cad-ring-label strong {
    font-size: 24px;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--cad-green-deep);
    font-variant-numeric: tabular-nums;
}
.cad-ring-label small {
    font-size: 9.5px;
    color: var(--cad-muted);
    margin-top: 3px;
}
.cad-score-note {
    font-size: 11px;
    font-style: italic;
    opacity: 0;
    transform: translateY(6px);
    transition: opacity 0.45s ease 0.3s, transform 0.45s ease 0.3s;
}
.cad-report.is-scored .cad-score-note {
    opacity: 1;
    transform: translateY(0);
}
.cad-meta {
    margin: 0 0 14px;
    padding: 0;
}
.cad-meta > div {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 5px 0;
    border-bottom: 1px dashed rgba(25, 25, 25, 0.08);
    font-size: 11px;
    opacity: 0;
    transform: translateY(6px);
    transition: opacity 0.35s ease, transform 0.35s ease;
}
.cad-meta > div:last-child {
    border-bottom: 0;
}
.cad-meta dt {
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--cad-muted);
    white-space: nowrap;
}
.cad-meta dt svg {
    width: 12px;
    height: 12px;
    color: var(--cad-green);
    flex-shrink: 0;
}
.cad-meta dd {
    margin: 0;
    font-weight: 700;
    text-align: right;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cad-meta > div.is-in {
    opacity: 1;
    transform: translateY(0);
}
.cad-factors-title {
    display: block;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--cad-ink);
    margin-bottom: 8px;
}
.cad-factor {
    margin-bottom: 8px;
}
.cad-factor-head {
    display: flex;
    justify-content: space-between;
    font-size: 10.5px;
    margin-bottom: 3px;
}
.cad-factor-head span:first-child {
    color: var(--cad-muted);
}
.cad-factor-val {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.cad-bar {
    height: 6px;
    border-radius: 999px;
    background: rgba(25, 25, 25, 0.08);
    overflow: hidden;
}
.cad-bar-fill {
    height: 100%;
    width: 0;
    border-radius: inherit;
    background: linear-gradient(90deg, #2A7A4F, var(--cad-green));
    transition: width 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}
.cad-ready {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 14px;
    padding: 7px 10px;
    border-radius: 8px;
    background: rgba(26, 92, 58, 0.08);
    color: var(--cad-green);
    font-size: 11px;
    font-weight: 700;
    opacity: 0;
    transform: translateY(6px);
    transition: opacity 0.4s ease, transform 0.4s ease;
}
.cad-ready svg {
    width: 14px;
    height: 14px;
    flex-shrink: 0;
}
.cad-report.is-ready .cad-ready {
    opacity: 1;
    transform: translateY(0);
}

/* Responsive --------------------------------------------------------------- */
@media (max-width: 1199px) {
    .cad-stage {
        --cad-panel-w: 404px;
        --fan: 0.84;
        height: 640px;
        max-width: 580px;
        perspective: 1400px;
    }
}

/* Stack deliberately above 1024: at 1024 the left track hits its 400px floor. */
@media (max-width: 1079px) {
    .hero-split {
        grid-template-columns: minmax(0, 1fr);
        gap: 36px;
        padding: 24px 0 40px;
    }
    .hero-split .hero-bold {
        text-align: center;
        max-width: 720px;
        margin: 0 auto;
        container-type: normal;
    }
    .hero-split .hero-bold h1 {
        font-size: clamp(34px, 5.2vw, 48px);
    }
    .hero-split .hero-bold .hero-lead {
        margin: 0 auto;
    }
    .hero-split .hero-bold .hero-buttons {
        justify-content: center;
    }
    .hero-split .checklist {
        align-items: center;
    }
    /* --fan:0 zeroes lateral offset AND yaw AND pitch in one place, so
       horizontal overflow becomes structurally impossible, not merely measured.
       --rise:1.3 restores the vertical peek the flattened Z alone would lose. */
    .cad-stage {
        --cad-panel-w: min(100%, 420px);
        --fan: 0;
        --rise: 1.3;
        height: 660px;
        max-width: 520px;
        perspective: 1000px;
        perspective-origin: 50% 46%;
    }
    /* With --fan:0 the cards are perfectly co-located, so the 3% of
       translucency left in the front card reads as ghost text from the ones
       behind it. Go fully opaque here; the glass edge is not visible anyway
       once nothing peeks out sideways. */
    .cad-demo:not(.is-resetting) .cad-panel.is-active,
    .cad-demo.is-complete:not(.is-resetting) .cad-panel[data-panel="3"] {
        background: #fff;
    }
}

@media (max-width: 768px) {
    /* the page's own .checklist padding rule must not re-apply inside the split */
    .hero-split .checklist {
        padding: 0;
        align-items: flex-start;
    }
}

@media (max-width: 560px) {
    .cad-stage {
        --cad-panel-w: 100%;
        --rise: 1.15;
        height: 640px;
        perspective: 900px;
    }
    /* below 380px .cad-score-note would otherwise outgrow the 88px ring */
    .cad-score-note {
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 4;
        line-clamp: 4;
        overflow: hidden;
    }
}

/* 13" laptops: keep the front card's Submit button above the fold. */
@media (min-width: 1080px) and (max-height: 840px) {
    .hero-split {
        padding: 0 0 24px;
    }
    .cad-stage {
        height: 600px;
        --rise: 0.82;
    }
}

/* Motion preferences: the script renders the finished report and skips the
   loop. renderFinal() sets all three panels is-done AND adds is-complete, which
   lands exactly on the finale pose -- the report front and centre with its two
   upstream stages fanned behind it. The static frame is the best frame of the
   animation, so there is nothing extra to build here; just stop the motion. */
@media (prefers-reduced-motion: reduce) {
    .cad-glow,
    .cad-caret,
    .cad-spinner {
        animation: none !important;
    }
    .cad-panel,
    .cad-haze,
    .cad-stage,
    .cad-arrow,
    .cad-flow-step,
    .cad-badge,
    .cad-score-note,
    .cad-meta > div,
    .cad-bar-fill,
    .cad-ring-fill,
    .cad-ready {
        transition: none !important;
    }
    .cad-demo.is-complete .cad-panel[data-panel="3"]::after {
        animation: none !important;
    }
}
