/* ==========================================================================
   TicketPulse design tokens — THE canonical source for the platform.

   Served to every host as a Razor Class Library static asset:
       <link rel="stylesheet" href="_content/World.Platform.DesignTokens/tokens.css" />

   WHY THIS FILE EXISTS
   Three apps had independently ported the design system and 22 shared tokens had
   drifted into disagreement — var(--tp-purple) rendered #6C2BD9 on ticketpulse.events
   and #440099 on PulseTV and Pulse Studios. A token that means two things is worse
   than a hardcoded colour, because it looks like it is under control. One definition
   lives here; an app that genuinely needs a different value overrides it under a
   [data-brand] scope below, where the difference is deliberate and visible.

   scripts/check-token-coverage.py fails CI if a second :root anywhere redefines one
   of these names, so the drift cannot silently return.

   Values are the design system's ("TicketPulse Design System", tokens/colors.css,
   typography.css, spacing.css). Where an app disagreed, the design system won —
   see the RESOLVED notes.

   No @import of Google Fonts here: this file names the families, it does not fetch them.
   Each host supplies the faces the way that suits it — Pulse Studios self-hosts all three
   as latin variable .woff2 from its own origin (wwwroot/fonts.css), so a creator on cellular
   at a venue pays for no third-party bytes; PulseTV requests them from the Google CDN. Either
   way the stacks below resolve for real rather than falling through to system fonts.
   ========================================================================== */

:root {
    /* ---- Primary: purple family ----
       RESOLVED: Apps.TicketPulse carried #6C2BD9/#4A1A9E/#8B5CF6 from the
       TP-Homepage-AdSlots prototype. The design system's values win, so the main
       consumer site moves to the deeper purple and matches its siblings. */
    --tp-purple: #440099;
    --tp-purple-dark: #2D0066;
    --tp-purple-light: #6B3FA0;

    /* ---- Ink & paper ---- */
    --tp-black: #1A1A2E;
    --tp-white: #FFFFFF;

    /* ---- Accents (the 10%) ---- */
    --tp-accent-orange: #FF6B35;
    --tp-accent-teal: #00C9A7;
    --tp-accent-gold: #FFD166;

    /* ---- Neutrals ---- */
    --tp-grey-bg: #F4F4F8;
    --tp-grey-border: #E0E0E6;
    --tp-grey-text: #6C6C80;

    /* ---- Neutral ramp ----
       The system shipped with three neutrals (bg, border, text) against 163 distinct
       near-neutral colours in the consumer surfaces, so most greys had nowhere to go.
       These nine are not invented: each is the most-used real value in its luminance
       band, so the surfaces that adopt them keep the colour they already had. Values
       within ~12 RGB of an existing token are deliberately absent — those snap to it
       instead of adding another near-duplicate.

       #F8F9FA is omitted for that reason — it is 6.7 from --tp-grey-bg and resolves
       to it. #EEEDF2 likewise has no entry: its nearest is --tp-grey-200 at 5.9. */
    --tp-grey-200: #E9ECEF;   /* lighter hairline than --tp-grey-border */
    --tp-grey-400: #9CA3AF;   /* muted/disabled text */
    --tp-grey-600: #595959;   /* secondary body copy */
    --tp-grey-700: #333333;
    --tp-grey-800: #212529;
    --tp-grey-900: #0E0E0E;
    --tp-ink-true: #000000;   /* true black, distinct from --tp-black's blue-violet ink */

    /* ---- Cool neutrals ----
       The internal tools (InCtrl, the payouts and promoter portals) were built on the
       Tailwind slate family, which leans blue where --tp-grey-* leans purple. Most of
       those values land within 12 RGB of the ramp above and resolve to it; these four
       do not, and snapping them would tint every admin screen toward the consumer
       brand. Ops tooling reading cooler than the marketing site is a reasonable thing
       for it to do, so the family is named rather than flattened. */
    --tp-steel-300: #CBD5E1;
    --tp-steel-500: #64748B;
    --tp-steel-600: #475569;
    --tp-steel-900: #0F172A;

    /* The purple-tinted slate the consumer site uses for secondary surfaces and headings.
       Too chromatic to sit in the ramp above and 53 RGB from --tp-black, so it is its
       own token rather than being snapped to either. */
    --tp-slate: #39364F;

    /* A red-orange distinct from Carnival Orange, used for alerts and sale flashes. */
    --tp-accent-red: #EB3616;

    /* ---- Extended purple family ---- */
    --pulse-purple: #4A00A8;
    --pulse-violet: #6A00FF;
    --pulse-plum: #2E0057;
    --pulse-lavender: #EAE2F7;
    --pulse-ink-overlay: #1A0A2E;

    /* ---- Accent tints ---- */
    --tp-purple-tint: rgba(68, 0, 153, 0.08);
    --tp-orange-tint: rgba(255, 107, 53, 0.12);
    --tp-teal-tint: rgba(0, 201, 167, 0.12);
    --tp-gold-tint: rgba(255, 209, 102, 0.18);
    --tp-gold-line: rgba(255, 209, 102, 0.4);   /* gold chip borders (BETA sticker, notices) */

    /* ---- Image overlay (brand-mandated for text on photos) ---- */
    --tp-overlay-purple: rgba(68, 0, 153, 0.70);
    --tp-overlay-gradient: linear-gradient(to top, rgba(26,26,46,0.85) 0%, rgba(26,26,46,0) 60%);
    --tp-hero-gradient: linear-gradient(135deg, #440099 0%, #2D0066 100%);

    /* ---- Readable foregrounds for the tint fills above (all >= 4.5:1) ---- */
    --tp-on-teal-tint: #00806C;
    --tp-on-orange-tint: #C2410C;
    --tp-on-gold-tint: #8A6100;

    /* ---- Semantic colour roles ----
       These names were in use across PaymentsService, InCtrl and the payouts
       surfaces, each with its own value. Stated once, in terms of the palette
       above so a role can never drift away from the brand.

       RESOLVED --tp-primary:   #6C2BD9 (PaymentsService) -> the brand purple.
       RESOLVED --tp-secondary: #4A1A9E (PaymentsService) and #B4380B (payouts)
                                were two unrelated ideas sharing a name. Secondary
                                means "the darker brand purple"; the payouts burnt
                                orange is a local accent and is renamed there.
       RESOLVED --tp-success:   #28A745 (Bootstrap 4 green) -> #10B981, which
                                Apps.TicketPulse already used as --tp-green.
       RESOLVED --tp-info:      #17A2B8 (Bootstrap 4) and #6C2BD9 (the brand purple
                                mis-assigned to an info role) -> Bootstrap 5's #0DCAF0.
       RESOLVED --tp-gold:      #D4AF37 and #F59E0B -> the design system's gold.
       RESOLVED --tp-teal:      #20C997 -> the design system's teal. */
    --tp-primary: var(--tp-purple);
    --tp-secondary: var(--tp-purple-dark);
    --tp-success: #10B981;
    --tp-warning: var(--tp-accent-gold);
    --tp-danger: #F43F5E;
    --tp-info: #0DCAF0;
    --tp-gold: var(--tp-accent-gold);
    --tp-teal: var(--tp-accent-teal);

    /* RESOLVED --tp-bg:     #FAFBFC / #F7F8FA -> the one page ground.
       RESOLVED --tp-border: #E8ECF1 / #E9EBF0 -> the one hairline.
       RESOLVED --tp-shadow: two different shadows -> the card shadow. */
    --tp-bg: var(--tp-grey-bg);
    --tp-border: var(--tp-grey-border);
    --tp-text: var(--tp-black);
    --tp-surface: var(--tp-white);

    /* ---- Type ----
       RESOLVED --font-sans/--font-mono: four near-identical stacks differing only
       in fallbacks. The design system's longer stacks win; they degrade further. */
    --font-sans: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --font-mono: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;
    --font-media: 'Space Grotesk', 'DM Sans', sans-serif;

    /* --font-body and --font-display were app identity choices (Inter, Archivo,
       Fraunces, Wix Madefor Display) competing for one name. The shared default is
       the sans; an app that wants its own face declares it under its brand scope. */
    --font-body: var(--font-sans);
    --font-display: var(--font-sans);

    --fw-regular: 400;
    --fw-medium: 500;
    --fw-semibold: 600;
    --fw-bold: 700;

    --fs-display: 60px;
    --fs-h1: 38px;
    --fs-h2: 30px;
    --fs-h3: 23px;
    --fs-body: 16px;
    --fs-caption: 14px;
    --fs-small: 12px;
    --fs-button: 16px;
    --fs-price: 22px;
    --fs-nav: 16px;

    --lh-display: 1.1;
    --lh-heading: 1.2;
    --lh-h2: 1.25;
    --lh-h3: 1.3;
    --lh-body: 1.6;
    --lh-caption: 1.5;
    --lh-tight: 1.0;

    --ls-display: -0.02em;
    --ls-heading: -0.01em;
    --ls-body: 0;
    --ls-caps: 0.06em;

    /* ---- Spacing (4px base) ---- */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-8: 32px;
    --space-10: 40px;
    --space-12: 48px;
    --space-16: 64px;
    --space-20: 80px;
    --space-24: 96px;

    /* ---- Radii ----
       RESOLVED --tp-radius-sm: PaymentsService had 10px against the system's 8px. */
    --tp-radius-sm: 8px;
    --tp-radius-md: 12px;
    --tp-radius-lg: 16px;
    --tp-radius-pill: 999px;
    --tp-radius-full: 50%;

    /* ---- Shadows ---- */
    --tp-shadow-card: 0 2px 12px rgba(68, 0, 153, 0.08);
    --tp-shadow-elevated: 0 8px 32px rgba(68, 0, 153, 0.12);
    --tp-shadow-focus: 0 0 0 3px rgba(107, 63, 160, 0.35);
    --tp-shadow: var(--tp-shadow-card);

    /* ---- Motion ----
       RESOLVED --tp-ease: Apps.TicketPulse baked a 0.25s duration into the easing
       token, so it could not be used as a timing function. It had no callers. */
    --tp-transition: all 0.2s ease;
    --tp-transition-fast: all 0.12s ease;
    --tp-ease: cubic-bezier(0.4, 0, 0.2, 1);

    /* ---- Layout ---- */
    --tp-hover-lift: scale(1.02);
    --tp-container: 1200px;
    --tp-container-narrow: 720px;
    --tp-email-width: 600px;
    --tp-header-height: 72px;

    /* ---- Semantic aliases ---- */
    --text-primary: var(--tp-black);
    --text-secondary: var(--tp-grey-text);
    --text-on-purple: var(--tp-white);
    --text-link: var(--tp-purple);
    --text-link-hover: var(--tp-purple-dark);

    --surface-page: var(--tp-grey-bg);
    --surface-card: var(--tp-white);
    --surface-brand: var(--tp-purple);
    --surface-brand-dark: var(--tp-purple-dark);
    --surface-input: var(--tp-grey-bg);

    --border-default: var(--tp-grey-border);
    --border-brand: var(--tp-purple);
    --border-focus: var(--tp-purple-light);

    --state-success: var(--tp-accent-teal);
    --state-warning: var(--tp-accent-gold);
    --state-urgent: var(--tp-accent-orange);

    --radius-control: var(--tp-radius-sm);
    --radius-card: var(--tp-radius-md);
    --radius-panel: var(--tp-radius-lg);
    --shadow-card: var(--tp-shadow-card);
    --shadow-pop: var(--tp-shadow-elevated);

    --text-display-size: var(--fs-display);
    --text-h1-size: var(--fs-h1);
    --text-body-size: var(--fs-body);
    --text-price-size: var(--fs-price);

    /* ---- Brand-scoped roles (default = master TicketPulse) ----
       Build against these four, then set data-brand on a wrapper to re-skin.
       RESOLVED --brand-primary / --brand-gradient: InCtrl restated the literals
       rather than pointing at the palette, which is how they drifted. */
    --brand-primary: var(--tp-purple);
    --brand-primary-dark: var(--tp-purple-dark);
    --brand-tint: var(--pulse-lavender);
    --brand-accent: var(--tp-accent-orange);
    --brand-gradient: var(--tp-hero-gradient);
    --tp-gradient: var(--tp-hero-gradient);
}

/* PulseTV — live streaming & media. Leads with Electric Violet. It sets no type of its
   own: the 28 Aug design review corrected its display face from Fraunces to Space Grotesk,
   which is what the master scope already says. */
[data-brand="pulsetv"] {
    --brand-primary: var(--pulse-violet);
    --brand-primary-dark: var(--tp-purple);
    --brand-tint: rgba(106, 0, 255, 0.10);
    --brand-accent: var(--tp-accent-orange);
    --brand-gradient: linear-gradient(135deg, #6A00FF 0%, #440099 100%);
}

/* Pulse Studios — production & creative services. Pulse Purple on plum. */
[data-brand="pulse-studios"] {
    --brand-primary: var(--pulse-purple);
    --brand-primary-dark: var(--pulse-plum);
    --brand-tint: rgba(74, 0, 168, 0.10);
    --brand-accent: var(--tp-accent-gold);
    --brand-gradient: linear-gradient(135deg, #4A00A8 0%, #2E0057 100%);
}
