/*
 * SUNO - Design Tokens
 * ============================================================================
 * The single source of truth for colour, type, shape, space, elevation and
 * motion. Loaded BEFORE index.css, which consumes these.
 *
 * This file replaces three overlapping colour systems that used to coexist:
 *   1. Bootswatch "Brite" (a whole second Bootstrap build, loaded from a CDN)
 *   2. --ewai-* in index.css, which were stock Bootstrap defaults, so no brand
 *   3. --brand-* in onboarding.css, the real ConnectHear teal/orange, scoped to
 *      a single page
 *
 * ---------------------------------------------------------------------------
 * TWO RULES THAT ARE NOT STYLE PREFERENCES
 * ---------------------------------------------------------------------------
 *
 * 1. Brand hue is not severity hue.
 *    SUNO dispatches emergency alerts. Colour here carries meaning: an operator
 *    reads red as "emergency" and amber as "warning". onboarding.css used to map
 *    brand teal onto BOTH --bs-primary and --bs-success, which made "success"
 *    and "brand" the same colour and drained the signal out of both. Severity
 *    tokens below are deliberately off the brand hues. Never alias them.
 *
 * 2. The bright brand teal cannot carry text.
 *    ConnectHear teal (#33cccc) is 1.97:1 on white -- it fails AA as text and it
 *    fails again with white text on top of it. It is kept for large fills,
 *    graphics and video overlays, always paired with dark text. Anything with a
 *    label on it, or that is itself a label, uses --suno-teal-700 or darker.
 *
 * Every foreground/background pair below is measured: text pairs clear WCAG AA
 * (4.5:1) and control boundaries, icons and focus rings clear 1.4.11 (3:1), in
 * both light and dark. Decorative hairlines carry no contrast duty by design.
 *
 * Dark values are defined three times over, for the three states a theme choice
 * can be in: an explicit dark choice, the system preference when no choice has
 * been made, and an explicit light choice that has to win on a dark machine.
 * See the block comment above the media query below. theme.js drives it, and
 * the switch is always wholesale -- per-section theme mixing is never correct.
 */

:root {
  /* ---------------------------------------------------------------- 1. BRAND
     ConnectHear teal and orange. 500 is the published brand hue; the darker
     steps exist because the brand hue is unusable for text. */
  --suno-teal-300: #8de2e2;
  --suno-teal-400: #64d8d8;
  --suno-teal-500: #33cccc;  /* brand hue - large fills only, dark text on top */
  --suno-teal-600: #279b9b;  /* 3.36:1 on white - icons, control borders       */
  --suno-teal-700: #1f7a7a;  /* 5.09:1 on white - actions, links, text        */
  --suno-teal-800: #186262;  /* 7.09:1 on white - hover / active               */
  --suno-teal-900: #124949;

  --suno-orange-300: #efb980;
  --suno-orange-400: #e9a053;
  --suno-orange-500: #e2821d;  /* brand hue - large fills only */
  --suno-orange-600: #ac6316;  /* 4.61:1 on white */
  --suno-orange-700: #884e11;  /* 6.68:1 on white */
  --suno-orange-800: #6d3e0e;

  /* ------------------------------------------------------------- 2. SEMANTIC
     What the UI actually references. Swapping these swaps the theme. */
  --suno-bg:              #f6f7f8;
  --suno-surface:         #ffffff;
  --suno-surface-raised:  #ffffff;

  /* Letterbox behind video and video placeholders. Deliberately NOT theme-
     dependent: a near-black surround is what a viewer expects around a frame in
     either theme, and switching it to a light fill in light mode would put the
     alert's own dark footage against glare. Off-black, per the rule above --
     this replaces a literal #000 that three rules used to paint. */
  --suno-media-bg:        #0b0e11;

  /* Loading skeleton: a resting field and the sheen that sweeps across it.
     These are a pair and the sheen must be the LIGHTER of the two in light mode
     and the lighter of the two in dark mode as well, so the sweep reads as a
     highlight travelling rather than as a shadow. The skeleton's mid-stop used
     to be a literal #eceff2, which on a dark background put a near-white band
     through the middle of the gradient on every pass. */
  --suno-skeleton-base:   #e4e8ec;
  --suno-skeleton-sheen:  #f3f5f7;

  --suno-text:            #14181c;  /* off-black, never #000 */
  --suno-text-secondary:  #4a545e;
  --suno-text-muted:      #66707a;  /* 5.04:1 on surface - still AA */

  --suno-border:          #d9dee3;  /* decorative hairline */
  --suno-border-control:  #717f8e;  /* 3.0:1 - input and control boundaries */

  --suno-action:          var(--suno-teal-700);
  --suno-action-hover:    var(--suno-teal-800);
  --suno-on-action:       #ffffff;
  --suno-ui:              var(--suno-teal-600);  /* icons, non-text marks */
  --suno-accent-text:     var(--suno-orange-700);

  /* ------------------------------------------------------------- 3. SEVERITY
     Alert state, not decoration. Distinct from brand on purpose (see rule 1).
     Ordered by escalation. */
  --suno-sev-info:      #1c5fa8;  /* 6.46:1 - advisory   */
  --suno-sev-ok:        #1b6b3a;  /* 6.54:1 - resolved   */
  --suno-sev-warning:   #8a5300;  /* 6.33:1 - watch      */
  --suno-sev-emergency: #b3261e;  /* 6.54:1 - emergency  */
  --suno-on-sev:        #ffffff;

  /* Tinted surfaces for callouts that carry a severity without being a badge (the
     API key panel, missing-vocabulary chips). Kept as tokens so they invert with
     the theme instead of pinning a page to a light background. */
  --suno-warning-surface: #fdf7e6;
  --suno-warning-edge:    #e6cf94;
  --suno-danger-surface:  #fdf6f5;
  --suno-danger-edge:     #e8b4ae;
  /* Completing the set. Bootstrap's .alert-info / .alert-success are built from its
     own *-bg-subtle variables, which are light-only unless something maps them --
     see the bridge in index.css §1b. */
  --suno-info-surface:    #eef4fb;
  --suno-info-edge:       #b8cfe8;
  --suno-ok-surface:      #eef6f1;
  --suno-ok-edge:         #a9cdb8;

  /* ---------------------------------------------------------------- 4. SHAPE
     One scale, tight. Precise radii read as instrumentation; 12-16px reads
     consumer. -full is only for genuinely circular things (avatars, dots),
     never for buttons. */
  --suno-radius-sm:   4px;
  --suno-radius-md:   6px;
  --suno-radius-full: 999px;

  /* ---------------------------------------------------------------- 5. SPACE
     4px base. Use these instead of ad-hoc Bootstrap mb-4 / py-5. */
  --suno-space-1:  4px;
  --suno-space-2:  8px;
  --suno-space-3:  12px;
  --suno-space-4:  16px;
  --suno-space-5:  20px;
  --suno-space-6:  24px;
  --suno-space-8:  32px;
  --suno-space-10: 40px;
  --suno-space-12: 48px;
  --suno-space-16: 64px;

  /* ----------------------------------------------------------------- 6. TYPE
     Archivo for UI, IBM Plex Mono for anything numeric or identifier-shaped:
     job ids, timestamps, counts, phone numbers, API keys. This app is full of
     them and they are far easier to scan and compare in a monospace.
     Both faces are self-hosted in static/fonts and declared in fonts.css. */
  --suno-font-sans: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;
  --suno-font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --suno-font-arabic: "Noto Sans Arabic", "Arial Unicode MS", Tahoma, sans-serif;

  --suno-text-xs:   0.75rem;   /* 12px */
  --suno-text-sm:   0.875rem;  /* 14px */
  --suno-text-base: 1.0625rem; /* 17px - raised from 16 for sustained reading */
  --suno-text-lg:   1.25rem;   /* 20px */
  --suno-text-xl:   1.5rem;    /* 24px */
  --suno-text-2xl:  2rem;      /* 32px */
  --suno-text-3xl:  2.5rem;    /* 40px */

  --suno-leading-tight: 1.15;
  --suno-leading-snug:  1.35;
  --suno-leading-body:  1.6;

  /* Display tracking is negative; small caps-y labels need positive. */
  --suno-tracking-tight: -0.02em;
  --suno-tracking-wide:  0.06em;

  --suno-measure: 65ch;  /* max line length for prose */

  /* ------------------------------------------------------------ 7. ELEVATION
     Exactly one shadow, for surfaces that genuinely float (modal, dropdown,
     toast). Everything else groups with a hairline or with space. Tinted to
     the UI's blue-grey rather than pure black. */
  --suno-shadow-overlay: 0 8px 24px -4px rgba(20, 24, 28, 0.18),
                         0 2px 6px -2px rgba(20, 24, 28, 0.12);

  /* --------------------------------------------------------------- 8. MOTION
     Short and unfussy. Every consumer must sit behind a
     prefers-reduced-motion guard. */
  --suno-duration-fast: 120ms;
  --suno-duration-base: 180ms;
  --suno-ease: cubic-bezier(0.2, 0, 0.2, 1);

  /* ---------------------------------------------------------------- 9. FOCUS
     One visible ring for the whole app, consumed by the :focus-visible rules in
     index.css §2 so it appears for keyboard users and not on mouse clicks. */
  --suno-focus-ring: 0 0 0 3px rgba(31, 122, 122, 0.45);
  --suno-focus-outline-width: 3px;

  /* ------------------------------------------------------------ 10. DISPLAY
     The scale in §6 tops out at 40px, which is a heading size, not a display
     size. These three steps exist for the few places that carry the page: the
     auth panel, a page's own title, an empty state that has to hold a whole
     screen on its own.

     Fluid rather than stepped, because the alternative is a 72px headline
     wrapping to four lines on a phone. clamp() reads min / preferred / max: the
     vw term does the scaling and the rem floor keeps it readable at 320px.

     Tracking goes further negative as size goes up -- letter-spacing that looks
     right at 17px looks loose at 72px. Leading goes below 1 of the em box for
     the same reason. */
  --suno-text-4xl: clamp(2.25rem, 1.55rem + 2.6vw, 3.25rem);   /*  36 ->  52 */
  --suno-text-5xl: clamp(2.75rem, 1.70rem + 4.0vw, 4.25rem);   /*  44 ->  68 */
  --suno-text-6xl: clamp(3.25rem, 1.85rem + 5.6vw, 5.50rem);   /*  52 ->  88 */

  --suno-leading-display:  1.04;
  --suno-tracking-display: -0.035em;
  --suno-tracking-display-tight: -0.045em;  /* 5xl and up only */

  /* Display weight. Archivo is a variable face over 400-700, so these are real
     interpolated instances and cost no extra download. */
  --suno-weight-display: 680;

  /* ---------------------------------------------------------- 11. ELEVATION+
     §7 has exactly one shadow, for things that genuinely float. That rule holds
     for overlays, but it left no way to express "this surface is one step above
     the page" without a border, which is why every card in the app is flat.

     Three steps, one light source (top, hence the negative y-spread on the
     ambient half of each pair), tinted to the UI's blue-grey rather than black.
     Each is two shadows: a tight contact shadow that reads as "resting on" and
     a wide ambient one that reads as "lifted". */
  --suno-shadow-xs: 0 1px 2px -1px rgba(20, 24, 28, 0.10),
                    0 1px 1px -1px rgba(20, 24, 28, 0.06);
  --suno-shadow-sm: 0 2px 6px -2px rgba(20, 24, 28, 0.12),
                    0 1px 2px -1px rgba(20, 24, 28, 0.08);
  --suno-shadow-md: 0 6px 16px -4px rgba(20, 24, 28, 0.14),
                    0 2px 4px -2px rgba(20, 24, 28, 0.08);

  /* A teal-tinted lift, for the one surface that is the product's payoff (the
     rendered alert). Tinted shadows carry the hue of what is above them. */
  --suno-shadow-accent: 0 10px 30px -8px rgba(31, 122, 122, 0.28),
                        0 3px 8px -3px rgba(20, 24, 28, 0.12);

  /* ------------------------------------------------------------- 12. LAYERS
     Was: raw 60 / 100 / -1 / -2 in index.css and 10000 / 10001 / 10002 in
     onboarding.css -- two unrelated scales, and a toast at 1090 that rendered
     UNDERNEATH onboarding.css's overlays.

     Aligned to Bootstrap's own scale, since its components are in this stack
     and fighting them is pointless: dropdown 1000, sticky 1020, fixed 1030,
     modal-backdrop 1050, modal 1055, popover 1070, tooltip 1080. Toast sits
     above all of them because it reports the outcome of what they did. */
  --suno-z-under:    -1;     /* decorative, behind content */
  --suno-z-base:      1;
  --suno-z-raised:   10;     /* overlapping editorial elements */
  --suno-z-sticky:   60;     /* in-page sticky panels (the preview stage) */
  --suno-z-nav:     100;     /* the navbar */
  --suno-z-overlay: 1050;    /* full-screen process overlays */
  /* A dialog opened FROM another dialog. Bootstrap gives every .modal the same
     1055, so which one paints on top comes down to DOM order -- which means a
     confirmation can open behind the thing it is confirming, look like nothing
     happened, and make a destructive action unreachable. Anything that confirms
     sits above anything that asks. */
  --suno-z-modal-over: 1065;
  --suno-z-toast:   1090;    /* above everything: it reports the outcome */

  /* --------------------------------------------------------- 13. MOTION+
     §8 covers state changes (hover, focus, border). It has no vocabulary for
     things that ENTER, which is why nothing in the app animates in.

     Two easings, deliberately different jobs:
       -out    decelerating, no overshoot. Anything carrying text: an operator
               reading a result should not watch it wobble into place.
       -spring one small overshoot. Physical, tactile controls only -- a press,
               a toggle, a card lifting to the cursor. Never on text.

     Every consumer sits behind a prefers-reduced-motion guard; see motion.css,
     which is the only file that reads these. */
  --suno-duration-slow:   320ms;
  --suno-duration-reveal: 520ms;

  --suno-ease-out:    cubic-bezier(0.16, 1, 0.30, 1);
  --suno-ease-spring: cubic-bezier(0.34, 1.42, 0.64, 1);

  /* Delay between siblings in a staggered group. 55ms is long enough to read as
     sequence and short enough that an 8-item list finishes in under half a
     second, so it never delays an operator who knows what they came to do. */
  --suno-stagger: 55ms;
  --suno-lift: -2px;   /* how far an interactive surface rises to the cursor */

  /* ------------------------------------------------------------ 14. TEXTURE
     Flat vector surfaces read as unfinished at large sizes. This is a single
     tileable fractal-noise SVG, inlined as a data URI: no network request, no
     raster asset, and it tints with whatever is under it because it is pure
     alpha. Opacity is per-use and deliberately low -- it should be felt, not
     seen. baseFrequency 0.8 is fine grain; lower values look like clouds.

     Static, not animated: an animated grain over a whole page is a WCAG 2.3.1
     (three-flashes) risk and a battery cost for zero information. */
  --suno-noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
  --suno-noise-opacity: 0.035;

  /* Ambient wash behind display type. A radial off-centre, not a 45deg linear
     fade -- the even diagonal gradient is the single most recognisable "AI
     default" surface. Colour comes from the brand teal at low alpha, so it
     stays a wash and never becomes a field that text has to survive on. */
  --suno-ambient: radial-gradient(120% 80% at 12% 0%,
                    rgba(51, 204, 204, 0.13) 0%,
                    rgba(51, 204, 204, 0.05) 38%,
                    transparent 72%);
}

/* ===========================================================================
   DARK THEME
   Brand teal inverts direction: the darker steps that work as text on white are
   too dark on a dark surface, so the action colour moves to teal-400 and its
   label goes near-black.

   Three selectors, deliberately, because "theme" has three states:
     - :root[data-theme="dark"]                        explicit choice: dark
     - :root:not([data-theme="light"]) under the media  system preference, when no
                                                        explicit choice was made
     - bare :root (the light block above)               everything else

   The media query is guarded with :not([data-theme="light"]) so that choosing
   light explicitly still wins on a machine set to dark. Without that guard the
   toggle only works in one direction.
   =========================================================================== */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --suno-bg:             #0e1216;
    --suno-surface:        #171c21;
    --suno-surface-raised: #1e242a;

    /* Sheen stays the lighter of the pair, as in light mode. */
    --suno-skeleton-base:  #232a31;
    --suno-skeleton-sheen: #2f383f;

    --suno-text:           #e9edf0;
    --suno-text-secondary: #b3bcc4;
    --suno-text-muted:     #8d979f;

    --suno-border:         #2b333b;
    --suno-border-control: #6f8090;

    --suno-action:       var(--suno-teal-400);
    --suno-action-hover: var(--suno-teal-300);
    --suno-on-action:    #0b2222;
    --suno-ui:           var(--suno-teal-500);
    --suno-accent-text:  var(--suno-orange-400);

    --suno-sev-info:      #8fbdf0;
    --suno-sev-ok:        #6fd398;
    --suno-sev-warning:   #e8b53d;
    --suno-sev-emergency: #ff9d95;
    --suno-on-sev:        #0e1216;

    --suno-warning-surface: #2a2113;
    --suno-warning-edge:    #5d4a24;
    --suno-danger-surface:  #2b1614;
    --suno-danger-edge:     #5e2a25;
    --suno-info-surface:    #12212f;
    --suno-info-edge:       #2b4a68;
    --suno-ok-surface:      #12241a;
    --suno-ok-edge:         #2c4a36;

    --suno-shadow-overlay: 0 8px 24px -4px rgba(0, 0, 0, 0.6),
                           0 2px 6px -2px rgba(0, 0, 0, 0.4);

    /* Black, not blue-grey: a tinted shadow needs a lighter surface under it to
       read as tint rather than as dirt. Alpha rises because the contrast
       between surface and shadow is far smaller on a dark ground. */
    --suno-shadow-xs: 0 1px 2px -1px rgba(0, 0, 0, 0.50),
                      0 1px 1px -1px rgba(0, 0, 0, 0.35);
    --suno-shadow-sm: 0 2px 6px -2px rgba(0, 0, 0, 0.55),
                      0 1px 2px -1px rgba(0, 0, 0, 0.40);
    --suno-shadow-md: 0 6px 16px -4px rgba(0, 0, 0, 0.60),
                      0 2px 4px -2px rgba(0, 0, 0, 0.40);
    --suno-shadow-accent: 0 10px 30px -8px rgba(51, 204, 204, 0.22),
                          0 3px 8px -3px rgba(0, 0, 0, 0.50);

    /* Grain needs more presence on a dark ground to be felt at all. */
    --suno-noise-opacity: 0.055;
    --suno-ambient: radial-gradient(120% 80% at 12% 0%,
                      rgba(51, 204, 204, 0.15) 0%,
                      rgba(51, 204, 204, 0.06) 38%,
                      transparent 72%);

    --suno-focus-ring: 0 0 0 3px rgba(100, 216, 216, 0.5);
  }
}

[data-theme="dark"] {
  --suno-bg:             #0e1216;
  --suno-surface:        #171c21;
  --suno-surface-raised: #1e242a;

  --suno-skeleton-base:  #232a31;
  --suno-skeleton-sheen: #2f383f;

  --suno-text:           #e9edf0;
  --suno-text-secondary: #b3bcc4;
  --suno-text-muted:     #8d979f;

  --suno-border:         #2b333b;
  --suno-border-control: #6f8090;

  --suno-action:       var(--suno-teal-400);
  --suno-action-hover: var(--suno-teal-300);
  --suno-on-action:    #0b2222;
  --suno-ui:           var(--suno-teal-500);
  --suno-accent-text:  var(--suno-orange-400);

  /* Severity has to lift off a dark surface, but must stay recognisably red /
     amber / green / blue -- an operator's colour association is the point. */
  --suno-sev-info:      #8fbdf0;
  --suno-sev-ok:        #6fd398;
  --suno-sev-warning:   #e8b53d;
  --suno-sev-emergency: #ff9d95;
  --suno-on-sev:        #0e1216;

  /* Tinted callout surfaces, inverted: a dark wash rather than a pale one. */
  --suno-warning-surface: #2a2113;
  --suno-warning-edge:    #5d4a24;
  --suno-danger-surface:  #2b1614;
  --suno-danger-edge:     #5e2a25;
  --suno-info-surface:    #12212f;
  --suno-info-edge:       #2b4a68;
  --suno-ok-surface:      #12241a;
  --suno-ok-edge:         #2c4a36;

  --suno-shadow-overlay: 0 8px 24px -4px rgba(0, 0, 0, 0.6),
                         0 2px 6px -2px rgba(0, 0, 0, 0.4);

  /* See the note in the media-query block above: black rather than blue-grey,
     and higher alpha, because the surface is already dark. */
  --suno-shadow-xs: 0 1px 2px -1px rgba(0, 0, 0, 0.50),
                    0 1px 1px -1px rgba(0, 0, 0, 0.35);
  --suno-shadow-sm: 0 2px 6px -2px rgba(0, 0, 0, 0.55),
                    0 1px 2px -1px rgba(0, 0, 0, 0.40);
  --suno-shadow-md: 0 6px 16px -4px rgba(0, 0, 0, 0.60),
                    0 2px 4px -2px rgba(0, 0, 0, 0.40);
  --suno-shadow-accent: 0 10px 30px -8px rgba(51, 204, 204, 0.22),
                        0 3px 8px -3px rgba(0, 0, 0, 0.50);

  --suno-noise-opacity: 0.055;
  --suno-ambient: radial-gradient(120% 80% at 12% 0%,
                    rgba(51, 204, 204, 0.15) 0%,
                    rgba(51, 204, 204, 0.06) 38%,
                    transparent 72%);

  --suno-focus-ring: 0 0 0 3px rgba(100, 216, 216, 0.5);
}
