/* =========================================================================
   ChoreoSync site — the LOOK layer (2026-08-26)
   Loaded after cs-dark.css. cs-dark.css repaints OLMO's light template dark;
   this file is the part that is ours: the glint, the tiles, the timeline, the
   editor section. Kept separate so the dark pass and the brand pass can be
   reasoned about — and reverted — independently.

   The motif Carlos named is the CIRCLE GLINT: the lit node that rides the
   playhead in the app. One definition, reused everywhere a moment is marked —
   step numbers, timeline handles, the operators in the Studio Sound equation.
   ========================================================================= */

/* ---------- The glint --------------------------------------------------
   A white core, a tight brand ring, and two rings of bloom. `currentColor`
   is deliberately NOT used: the glint is always brand-lit, whatever it sits
   on, so it reads as the same object every time. */
.cs-glint {
    position: relative;
    display: inline-block;
    width: 13px; height: 13px;
    border-radius: 50%;
    background: #fff;
    box-shadow:
        0 0 0 4px rgba(var(--cs-primary-rgb), .30),
        0 0 14px 3px rgba(var(--cs-primary-rgb), .75),
        0 0 34px 10px rgba(var(--cs-primary-rgb), .35);
    flex: 0 0 auto;
}
.cs-glint-lg { width: 18px; height: 18px; }

/* Ring form — an open circle with the same bloom, for step numbers and the
   +/= operators. Sized by font-size so one class covers every use. */
.cs-glint-ring {
    display: inline-flex; align-items: center; justify-content: center;
    width: 3.4em; height: 3.4em;
    border-radius: 50%;
    border: 2px solid rgba(var(--cs-primary-rgb), .85);
    background: radial-gradient(circle at 50% 50%, rgba(var(--cs-primary-rgb), .28) 0%, rgba(var(--cs-primary-rgb), 0) 70%);
    box-shadow:
        0 0 18px rgba(var(--cs-primary-rgb), .45),
        inset 0 0 18px rgba(var(--cs-primary-rgb), .25);
    color: #fff;
    font-family: 'Manrope', sans-serif;
    font-weight: 800;
    line-height: 1;
}

/* ---------- Section eyebrow ---------- */
.cs-eyebrow {
    display: inline-flex; align-items: center; gap: .6rem;
    margin-bottom: 1.1rem;
    font-size: .78rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
    color: #b79dff;
}

/* ---------- The close ---------------------------------------------------
   ⚠ .cs-cta-band / .cs-chips / .cs-chip / .cs-cta-art are GONE (2026-08-26).
   They styled the old two-band ending — "the ChoreoSync app" followed by "your
   next choreo is waiting" — which is one band now. See inc-cta.php.

   Copy left, the finished article right, on the section itself rather than
   inside a bordered card: the card was the "generic SaaS block" note. */
.cs-close { position: relative; overflow: hidden; padding: var(--cs-band) 0; }
.cs-close-grid {
    position: relative; z-index: 1;
    display: grid;
    grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
    align-items: center;
    gap: clamp(2rem, 5vw, 4rem);
}
.cs-close-txt p.p-lg { color: var(--cs-body); margin: .9rem 0 1.6rem; max-width: 34ch; }
.cs-close-badges { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 1.75rem; }
.cs-close-foot { color: var(--cs-muted); font-size: .9rem; margin: 1.1rem 0 0; }

.cs-close-art { position: relative; margin: 0; text-align: center; }
.cs-close-art .cs-glow { inset: -6% -10%; }
.cs-close-art .cs-device { position: relative; z-index: 1; }
.cs-close-art .cs-device > img { width: auto; max-width: none; height: 460px; }
@media (max-width: 767px) {
    .cs-close { padding: 3rem 0 3.25rem; }
    .cs-close-grid { grid-template-columns: 1fr; gap: 2rem; }
    .cs-close-art .cs-device > img { height: min(44vh, 350px); }
}

/* ---------- Motion -----------------------------------------------------
   The playhead glint breathes; nothing else moves. Honored only when the
   viewer has not asked for less motion. */
@media (prefers-reduced-motion: no-preference) {
    @keyframes cs-pulse {
        0%, 100% { opacity: .55; transform: scale(1); }
        50%      { opacity: 1;   transform: scale(1.12); }
    }
    .cs-pulse { animation: cs-pulse 2.6s ease-in-out infinite; transform-origin: center; }
}

/* ⚠ .cs-feature-list is GONE (2026-08-26) — it bulleted the editor's
   21-control disclosure, which no longer exists. */

/* ---------- Pricing, pre-launch ---------------------------------------
   An inert button is a LABEL, not a control: it takes no focus and no
   pointer, so keyboard users are never sent to a button that does nothing. */
.cs-btn-inert {
    cursor: default;
    opacity: .75;
    pointer-events: none;
}
.cs-plan-note { color: #b79dff; margin-top: .75rem; }


/* =========================================================================
   THE THREE LAYERS (2026-08-26)

   The page reads as, in this order and never any other:

     1. real ChoreoSync UI   — the screenshots and captures
     2. circular glints/glow — light catching the interface
     3. controlled confetti  — energy

   PRODUCT FIRST. The glow supports the product; the confetti adds energy;
   neither is allowed to compete with a screenshot or a line of type. Both
   layers sit at z-index 0 with the product raised above them, and both are
   pointer-events:none so nothing here can ever eat a tap.

   ⚠ Neither is decoration to sprinkle. A section gets them because a moment
   in it earns them — the hero, a product screenshot, the sync lock, Studio
   Sound, the closing ask. Sections without a moment get nothing, and that
   restraint is what keeps them recognizable as ours.
   ========================================================================= */

/* ---------- Confetti ---------------------------------------------------
   Markup from cs_confetti() in home/inc/inc-viz.php. Every particle carries
   its own position, scale, opacity, depth and phase as custom properties, so
   this file describes ONE particle and the field falls out of it.

   ⚠ Every particle carries a BLOOM, not just a fill. That is the whole
   difference between this reading as ChoreoSync and reading as dust: the
   glint is a lit core with a halo, and the confetti is the same object at
   small scale. The first pass shipped flat dots at .10–.30 alpha and was
   invisible on the canvas. If the field ever starts pulling the eye off a
   screenshot, lower opacity — never remove the bloom, and never move a
   particle. */
.cs-confetti {
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
    /* Scroll parallax, written by the handler in cs_confetti_script().
       Stays 0 with reduced motion or no JS, which is a correct field. */
    --cs-par: 0px;
    transform: translate3d(0, var(--cs-par), 0);
}
/* The hero is the densest the field ever gets; a seam is the lightest. */
.cs-confetti-hero  { --cs-cf-size: 12px; }
.cs-confetti-moment{ --cs-cf-size: 11px; }
.cs-confetti-soft  { --cs-cf-size:  9px; }
.cs-confetti-seam  { --cs-cf-size:  8px; }

.cs-cf {
    position: absolute;
    left: var(--x);
    top: var(--y);
    width:  calc(var(--cs-cf-size, 7px) * var(--s));
    height: calc(var(--cs-cf-size, 7px) * var(--s));
    border-radius: 50%;
    opacity: var(--o);
    /* The glint recipe at particle scale: a lit core and a halo, sized off
       the particle so a big one blooms further than a small one. */
    background: var(--cs-cf-core, rgb(var(--cs-primary-rgb)));
    box-shadow:
        0 0 calc(var(--cs-cf-size, 9px) * var(--s) * 0.9) var(--cs-cf-halo, rgba(var(--cs-primary-rgb), .85)),
        0 0 calc(var(--cs-cf-size, 9px) * var(--s) * 2.2) var(--cs-cf-halo-far, rgba(var(--cs-primary-rgb), .45));
    transform: rotate(var(--rot));
}
/* Mostly purple and violet, white as the accent that keeps the field from
   flattening into a haze. No fourth color — this is the whole palette. */
.cs-cf-p {
    --cs-cf-core: rgb(var(--cs-primary-rgb));
    --cs-cf-halo: rgba(var(--cs-primary-rgb), .85);
    --cs-cf-halo-far: rgba(var(--cs-primary-rgb), .45);
}
.cs-cf-v {
    --cs-cf-core: #8B5CF6;
    --cs-cf-halo: rgba(139, 92, 246, .85);
    --cs-cf-halo-far: rgba(139, 92, 246, .45);
}
.cs-cf-w {
    --cs-cf-core: #fff;
    --cs-cf-halo: rgba(226, 214, 255, .90);
    --cs-cf-halo-far: rgba(var(--cs-primary-rgb), .55);
}

/* THREE SHAPES. Dots carry the field; bars and wave fragments are the site's
   own vocabulary at particle scale — this product draws waveforms all day, so
   its confetti is made of the same strokes rather than generic specks. */
.cs-cf-bar {
    width:  calc(var(--cs-cf-size, 9px) * var(--s) * 1.45);
    height: calc(var(--cs-cf-size, 9px) * var(--s) * 0.38);
    border-radius: 2px;
}
/* A wave fragment: three strokes of a waveform, drawn with the box and its two
   pseudo-elements so it stays one element in the markup. */
.cs-cf-wave {
    width:  calc(var(--cs-cf-size, 9px) * var(--s) * 0.26);
    height: calc(var(--cs-cf-size, 9px) * var(--s) * 1.35);
    border-radius: 2px;
}
.cs-cf-wave::before,
.cs-cf-wave::after {
    content: "";
    position: absolute;
    top: 50%;
    width: 100%;
    border-radius: 2px;
    background: inherit;
    box-shadow: inherit;
}
.cs-cf-wave::before { left: -240%; height: 58%;  transform: translateY(-50%); }
.cs-cf-wave::after  { left:  240%; height: 78%;  transform: translateY(-50%); }

/* ---------- Circle glow ------------------------------------------------
   Markup from cs_glow(). The glint grown to section scale, and it keeps all
   four parts: bloom, rim, primary glint, secondary glint.

   ⚠ Do not reduce this to the bloom alone. A bare radial-gradient behind a
   screenshot is exactly the generic-SaaS background this replaces; the rim
   and the two glints are what make it read as light on an interface. */
.cs-glow {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
}

/* CONTROLLED bloom: tight stops and a small blur. It is lighting the product,
   not washing the section — the last stop lands well inside the box. */
.cs-glow-bloom {
    position: absolute;
    left: 50%; top: 50%;
    width: var(--gw, 78%);
    aspect-ratio: 1;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background: radial-gradient(closest-side,
        rgba(var(--cs-primary-rgb), .46) 0%,
        rgba(var(--cs-primary-rgb), .22) 42%,
        rgba(139, 92, 246, .10) 66%,
        rgba(var(--cs-primary-rgb), 0) 100%);
    filter: blur(6px);
}

/* The edge highlight — a rim, lit from above. Without it the bloom dissolves
   at its own border and stops being a form. */
.cs-glow-edge {
    position: absolute;
    left: 50%; top: 50%;
    width: calc(var(--gw, 78%) * .84);
    aspect-ratio: 1;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, .055);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, .10),
        inset 0 22px 44px -34px rgba(255, 255, 255, .50);
}

/* The two glints — the SAME recipe as .cs-glint, at two sizes. A larger
   primary and a smaller secondary: one light source, one highlight. */
.cs-glow-a,
.cs-glow-b {
    position: absolute;
    border-radius: 50%;
    background: #fff;
    box-shadow:
        0 0 0 4px rgba(var(--cs-primary-rgb), .30),
        0 0 14px 3px rgba(var(--cs-primary-rgb), .75),
        0 0 34px 10px rgba(var(--cs-primary-rgb), .35);
}
.cs-glow-a { width: 14px; height: 14px; }
.cs-glow-b { width:  8px; height:  8px; opacity: .78; }

/* Variants place the light for each moment. The glints sit near the EDGE of
   the bloom, not in the middle of it — light catches an interface at its
   corners, and a glint dead-centre behind a screenshot just looks like a
   dot someone forgot to remove. */
.cs-glow-screen { --gw: 86%; }
/* The hero screen is the largest product visual on the site, and it is now the
   section's ONLY circle — its light scales to match. */
.cs-hero-stage > .cs-glow-screen { --gw: 104%; }
.cs-glow-screen .cs-glow-a { left: 8%;  top: 26%; }
.cs-glow-screen .cs-glow-b { right: 12%; bottom: 30%; }

.cs-glow-sync   { --gw: 62%; }
.cs-glow-sync   .cs-glow-a { left: 22%; top: 16%; }
.cs-glow-sync   .cs-glow-b { right: 24%; bottom: 18%; }

.cs-glow-room   { --gw: 70%; }
.cs-glow-room   .cs-glow-a { right: 18%; top: 22%; }
.cs-glow-room   .cs-glow-b { left: 26%;  bottom: 24%; }

.cs-glow-cta    { --gw: 66%; }
.cs-glow-cta    .cs-glow-a { left: 16%; top: 20%; }
.cs-glow-cta    .cs-glow-b { right: 20%; top: 62%; }

/* Anything the glow or the confetti sits behind has to be raised out of it —
   the product and the words are layer 1 and are always on top.

   ⚠ TWO LISTS, and they must stay two. A positioned element with z-index:0
   paints ABOVE non-positioned block content, so the fields would cover the
   page if nothing were raised — but half of what needs raising is ALREADY
   position:absolute (the hero screen, the hero track, and both sync
   annotations, which are absolutely placed against their parents).
   Forcing those to position:relative drops them back into flow and destroys
   the composition. Raise them with z-index ALONE. Only the genuinely static
   boxes below get position:relative. */
.cs-hero-stage > .cs-hero-screen,
.cs-tracks > .cs-tracks-head,
.cs-tracks > .cs-tracks-lock,
.cs-room-ui,
.cs-editor-shot { z-index: 1; }

/* Static content — safe to position, and the .container rule catches every
   copy block in one go rather than naming each one. */
.cs-hero > .container,
.cs-sync > .container,
.cs-editor > .container,
.cs-room > .container,
.cs-tracks > .cs-track,
.cs-close-grid { position: relative; z-index: 1; }

/* A glow dropped INSIDE a <figure> sits behind that figure's OWN contents,
   for the same painting-order reason. The editor shot and the CTA art are
   already position:relative and need nothing; the mixer is not. */
.cs-room-ui > figcaption { position: relative; z-index: 1; }

/* ---------- Motion, layers 2 and 3 -------------------------------------
   Slow glint drift, faint glow breathing, tiny confetti movement. Nothing
   bounces and nothing announces its loop: every duration is long, every
   easing is ease-in-out, and the confetti phases are staggered by a negative
   delay so the field is never caught breathing in unison.

   Everything below is inside no-preference. With reduced motion requested
   the field, the bloom and the glints are simply still — which is a complete
   composition, not a degraded one. */
@media (prefers-reduced-motion: no-preference) {

    /* Tiny movement, scaled by depth: a near particle travels further than a
       far one, which is what sells the field as having depth at all. */
    @keyframes cs-cf-drift {
        0%, 100% { transform: translate3d(0, 0, 0) rotate(var(--rot)); }
        50%      { transform: translate3d(calc(var(--dp) * 2px), calc(var(--dp) * -5px), 0)
                              rotate(calc(var(--rot) + 6deg)); }
    }
    .cs-cf { animation: cs-cf-drift var(--dur) ease-in-out var(--dl) infinite; }

    /* Breathing, not pulsing — 1.5% of scale over nine seconds. */
    @keyframes cs-glow-breathe {
        0%, 100% { opacity: .88; transform: translate(-50%, -50%) scale(1); }
        50%      { opacity: 1;   transform: translate(-50%, -50%) scale(1.015); }
    }
    .cs-glow-bloom { animation: cs-glow-breathe 9s ease-in-out infinite; }

    /* The glints drift a few pixels on their own, slower clocks. Two
       different durations so they never arrive together. */
    @keyframes cs-glint-drift-a {
        0%, 100% { transform: translate3d(0, 0, 0); }
        50%      { transform: translate3d(5px, -7px, 0); }
    }
    @keyframes cs-glint-drift-b {
        0%, 100% { transform: translate3d(0, 0, 0); }
        50%      { transform: translate3d(-6px, 5px, 0); }
    }
    .cs-glow-a { animation: cs-glint-drift-a 15s ease-in-out infinite; }
    .cs-glow-b { animation: cs-glint-drift-b 19s ease-in-out -4s infinite; }
}

/* ---------- Small screens ----------------------------------------------
   The field thins out and the bloom tightens. A phone has a fraction of the
   canvas, so the same particle count that reads as light on a desktop reads
   as noise here — and noise behind a screenshot is the one thing this whole
   system is not allowed to become. */
@media (max-width: 767px) {
    .cs-confetti-hero   { --cs-cf-size: 9px; }
    .cs-confetti-moment { --cs-cf-size: 8px; }
    .cs-confetti-soft,
    .cs-confetti-seam   { --cs-cf-size: 7px; }
    /* ⚠ The far layer used to be display:none here. It is only DIMMED now —
       hiding a third of the field on phones hid the feature from the one
       device it actually gets checked on. */
    .cs-cf[style*="--dp:3"] { opacity: calc(var(--o) * .7); }
    .cs-glow-screen { --gw: 96%; }
    .cs-glow-bloom  { filter: blur(4px); }
}
