/* ============================================================
   TonePerks — Design Tokens
   Source of truth: "TonePerks Brand Kit.pdf" (Brand Guidelines, 2026)

   Typeface  : Montserrat (single family — display and body)
   Palette   : deep purple -> vibrant pink, grounded on purple-black
   Iconography: 2px stroke outline, 24 / 32 / 48 / 64 ladder

   Montserrat is loaded from index.html via <link rel="preconnect"> +
   stylesheet, NOT via @import here — @import inside CSS serialises the
   font request behind the stylesheet and delays first paint.
   ============================================================ */

:root {

  /* ==========================================================
     1. BRAND COLOR — exact values from the brand kit
     ========================================================== */

  /* --- Primary --- */
  --tp-purple:      #8C006E;   /* TonePerks Purple  rgb(140,  0, 110) */
  --tp-pink:        #F03278;   /* TonePerks Pink    rgb(240, 50, 120) */
  --tp-dark:        #1A0A1A;   /* TonePerks Dark    rgb( 26, 10,  26) */

  /* --- Secondary --- */
  --tp-purple-mid:  #B40F69;   /* Mid Purple */
  --tp-pink-light:  #F472B6;   /* Light Pink */
  --tp-offwhite:    #FDF6FB;   /* Off White  */
  --tp-muted:       #6B5870;   /* Muted      */

  /* --- Derived tints & shades (not in the kit; interpolated from it) --- */
  --tp-purple-deep: #5E004A;   /* pressed / deepest purple            */
  --tp-purple-soft: #F3E2EE;   /* purple wash for soft backgrounds    */
  --tp-pink-deep:   #C41560;   /* pressed pink                        */
  --tp-pink-soft:   #FDE4EF;   /* pink wash for badges / highlights   */
  --tp-pink-tint:   #FBD0E2;   /* stronger pink wash                  */

  /* ==========================================================
     2. NEUTRAL RAMP
     Warm, purple-tinted greys interpolated between Dark #1A0A1A,
     Muted #6B5870 and Off White #FDF6FB. There is deliberately no
     blue and no green anywhere in this system — the previous
     navy/teal/green scale is not part of the TonePerks brand.
     ========================================================== */

  /* Foreground */
  --tp-fg-1:  #1A0A1A;   /* headings, primary text   19.07:1 on white */
  --tp-fg-2:  #453247;   /* body copy                 10.5:1 on white */
  --tp-fg-3:  #6B5870;   /* secondary / muted          6.45:1 on white */
  --tp-fg-4:  #7D6B84;   /* placeholders               4.88:1 on white — clears AA */

  /* Surfaces (light) */
  --tp-bg-1:  #FFFFFF;   /* primary surface        */
  --tp-bg-2:  #FDF6FB;   /* Off White — page tint  */
  --tp-bg-3:  #F7EAF3;   /* sunken / hover surface */
  --tp-bg-4:  #F0DDEA;   /* stronger sunken        */

  /* Surfaces (dark) — purple-black, per "Dark grounds the brand with sophistication" */
  --tp-dark-1: #1A0A1A;  /* full-bleed dark ground */
  --tp-dark-2: #26102A;  /* raised card on dark    */
  --tp-dark-3: #331740;  /* hover card on dark     */
  --tp-dark-4: #412050;  /* divider on dark        */

  /* Borders. #EFE0EB is only ~1.19:1 on white — invisible as structure
     once it is carrying a ruled grid rather than decorating a card, so
     the default hairline is darkened to roughly 1.6:1. */
  --tp-border:        #E3CEDD;
  --tp-border-strong: #CBAAC2;
  --tp-border-dark:   rgba(255, 255, 255, 0.10);
  --tp-border-dark-2: rgba(255, 255, 255, 0.18);

  /* Text on dark grounds — kept above the AA floor.
     rgba(255,255,255,0.55) on #1A0A1A is only ~4.1:1 and must not be
     used for body copy; these three are the sanctioned values. */
  --tp-on-dark-1: #FFFFFF;                      /* 19.07:1 */
  --tp-on-dark-2: rgba(255, 255, 255, 0.82);    /*  ~12.4:1 */
  --tp-on-dark-3: rgba(255, 255, 255, 0.66);    /*   ~7.9:1 — smallest safe body value */

  /* ==========================================================
     3. SEMANTIC
     ========================================================== */
  /* Success is drawn from the brand, not from a stock mint green — the
     kit has no green, so the previous green-on-mint pair was foreign to
     it. Purple on the purple wash is 7.2:1.
     Failure keeps a red. Signalling an error in a non-red hue is a
     usability regression that outweighs strict palette purity, so this
     is a deliberate, documented exception — the only one. */
  --tp-success:    #8C006E;
  --tp-success-bg: #F3E2EE;
  --tp-danger:     #B0182F;
  --tp-danger-bg:  #FBE7EA;
  --tp-focus:      #F03278;   /* focus rings use brand pink — never removed */

  /* ==========================================================
     4. GRADIENTS

     --tp-grad-wave  : the signature logo gradient. DECORATIVE ONLY —
                       fills, rules, marks, oversized numerals. Its pink
                       end is 3.87:1 against white, so nothing carrying
                       small text may sit on it.
     --tp-grad-cta   : the text-bearing gradient. Stops short of full
                       pink so white text stays >= 6.5:1 across its
                       entire length.
     ========================================================== */
  --tp-grad-wave:      linear-gradient(90deg,  #8C006E 0%, #F03278 100%);
  --tp-grad-wave-d:    linear-gradient(135deg, #8C006E 0%, #F03278 100%);
  --tp-grad-cta:       linear-gradient(135deg, #8C006E 0%, #B40F69 100%);
  --tp-grad-deep:      linear-gradient(150deg, #1A0A1A 0%, #4A0342 55%, #8C006E 100%);
  --tp-grad-soft:      linear-gradient(135deg, #FDE4EF 0%, #F3E2EE 100%);
  /* Gradient text must never pass through a stop that is unreadable on its
     own ground. Purple #8C006E is 2.12:1 on Dark; Pink #F03278 is 3.87:1 on
     white. So the text gradient is split by ground rather than shared:
       on light -> purple .. mid purple   (8.98 .. 6.59, legal at any size)
       on dark  -> pink .. light pink     (4.93 .. 7.19, legal at any size)  */
  --tp-grad-text-light: linear-gradient(90deg, #8C006E, #B40F69, #8C006E);
  --tp-grad-text-dark:  linear-gradient(90deg, #F03278, #F472B6, #F03278);

  /* ==========================================================
     5. TYPOGRAPHY — Montserrat
     Fallback stack is verbatim from the brand kit.
     ========================================================== */
  --tp-font: "Montserrat", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --tp-font-mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, monospace;

  /* Weights — the kit's roles mapped onto Montserrat's range.
     The wordmark itself is LIGHT (300); display headings are Bold/
     ExtraBold; labels are Bold caps. */
  --tp-w-light:    300;
  --tp-w-regular:  400;
  --tp-w-medium:   500;
  --tp-w-semibold: 600;
  --tp-w-bold:     700;
  --tp-w-black:    800;

  /* Montserrat is a wide geometric face. Uppercase display type needs
     negative tracking to hold together; small caps labels need a lot of
     positive tracking to breathe. Both are encoded here. */

  /* Display — hero. Montserrat is wide, so display sizes carry hard
     negative tracking and a sub-1 line height to hold together. */
  --tp-display-size:   clamp(3rem, 7.4vw, 6.5rem);
  --tp-display-weight: 800;
  --tp-display-line:   0.96;
  --tp-display-track:  -0.04em;

  /* H1 / section titles — deliberately close to display size. The deck
     sets section titles very large; timid section headings were the
     single biggest thing making the first pass read as a template. */
  --tp-h1-size:   clamp(2.25rem, 5.2vw, 4.25rem);
  --tp-h1-weight: 800;
  --tp-h1-line:   1.02;
  --tp-h1-track:  -0.035em;

  /* H2 — kit: 32pt SemiBold */
  --tp-h2-size:   clamp(1.5rem, 2.4vw, 2rem);
  --tp-h2-weight: 600;
  --tp-h2-line:   1.2;
  --tp-h2-track:  -0.015em;

  /* H3 — card titles */
  --tp-h3-size:   1.1875rem;   /* 19px */
  --tp-h3-weight: 600;
  --tp-h3-line:   1.3;
  --tp-h3-track:  -0.01em;

  /* Body — kit: 14–16pt Regular */
  --tp-body-lg-size: 1.125rem;  /* 18px */
  --tp-body-lg-line: 1.65;
  --tp-body-size:    1rem;      /* 16px */
  --tp-body-line:    1.65;
  --tp-body-sm-size: 0.875rem;  /* 14px */
  --tp-body-sm-line: 1.6;

  /* Label / CTA — kit: 12pt Bold, CAPS */
  --tp-label-size:   0.75rem;   /* 12px */
  --tp-label-weight: 700;
  --tp-label-track:  0.16em;

  /* Eyebrow — the wide-tracked section kicker */
  --tp-eyebrow-size:  0.6875rem; /* 11px */
  --tp-eyebrow-track: 0.22em;

  /* Caption — kit: 10pt Regular */
  --tp-caption-size: 0.75rem;    /* 12px, floored up from 10pt for screen */
  --tp-caption-line: 1.5;

  /* Oversized deck numerals ("01", "02", ...) — set light and huge */
  --tp-numeral-size:   clamp(3.5rem, 7vw, 6rem);
  --tp-numeral-weight: 300;
  --tp-numeral-track:  -0.04em;

  /* ==========================================================
     6. SPACING — 4 / 8 base
     ========================================================== */
  --tp-s-1:  0.25rem;   /*  4 */
  --tp-s-2:  0.5rem;    /*  8 */
  --tp-s-3:  0.75rem;   /* 12 */
  --tp-s-4:  1rem;      /* 16 */
  --tp-s-5:  1.5rem;    /* 24 */
  --tp-s-6:  2rem;      /* 32 */
  --tp-s-7:  3rem;      /* 48 */
  --tp-s-8:  4rem;      /* 64 */
  --tp-s-9:  6rem;      /* 96 */
  --tp-s-10: 8rem;      /* 128 */

  /* Layout */
  --tp-maxw:    1280px;
  --tp-gutter:  2rem;
  --tp-measure: 68ch;

  /* ==========================================================
     7. RADII
     The brand deck is flat and geometric: hard-cut colour fields,
     rules, and registration marks. Structural surfaces therefore
     have NO radius. The only genuinely round form in the identity
     is the waveform's pill cap, so the pill is reserved for the
     things that behave like the mark — buttons and badges.
     ========================================================== */
  --tp-r-0:    0;
  --tp-r-xs:   2px;
  --tp-r-pill: 999px;

  /* ==========================================================
     7b. EDITORIAL CHROME
     The deck frames every page: a strip across the top, a rule and
     rotated wordmark up the right edge, a solid block in the
     bottom-left corner. On the web these become fixed chrome, and
     the rail is a real layout inset (body padding), not an overlay
     floating on top of the content.
     ========================================================== */
  --tp-rail-w:    56px;
  --tp-rail-w-sm: 22px;
  --tp-topbar-h:  6px;

  /* ==========================================================
     8. ELEVATION — tinted with the brand purple, never neutral grey.
     ========================================================== */
  --tp-shadow-sm: 0 1px 2px  rgba(26, 10, 26, 0.06),
                  0 1px 3px  rgba(26, 10, 26, 0.04);
  --tp-shadow-md: 0 6px 16px -4px rgba(26, 10, 26, 0.10),
                  0 2px 6px  -2px rgba(26, 10, 26, 0.06);
  --tp-shadow-lg: 0 24px 48px -12px rgba(26, 10, 26, 0.16),
                  0 8px 16px  -4px rgba(26, 10, 26, 0.08);
  --tp-shadow-xl: 0 40px 80px -20px rgba(26, 10, 26, 0.22),
                  0 12px 24px -8px  rgba(26, 10, 26, 0.10);
  /* Brand-tinted lift for primary CTAs */
  --tp-shadow-cta: 0 10px 24px -6px rgba(240, 50, 120, 0.42),
                   0 4px  10px -2px rgba(140,  0, 110, 0.28);

  /* ==========================================================
     9. MOTION
     Sound has attack and decay, not bounce. Every curve here is
     ease-out: quick to start, settling slowly. Nothing overshoots.
     ========================================================== */
  --tp-ease:      cubic-bezier(0.22, 0.68, 0.20, 1.00);  /* standard  */
  --tp-ease-out:  cubic-bezier(0.16, 1.00, 0.30, 1.00);  /* decay     */
  --tp-ease-in:   cubic-bezier(0.55, 0.00, 1.00, 0.45);  /* attack    */

  --tp-dur-1: 120ms;   /* micro — colour, opacity        */
  --tp-dur-2: 220ms;   /* standard — hover, focus        */
  --tp-dur-3: 380ms;   /* deliberate — cards, panels     */
  --tp-dur-4: 620ms;   /* reveal                         */
  --tp-dur-5: 900ms;   /* hero entrance                  */

  /* Icon size ladder, from the kit */
  --tp-icon-ui:      24px;
  --tp-icon-card:    32px;
  --tp-icon-feature: 48px;
  --tp-icon-hero:    64px;
  --tp-icon-stroke:  2px;
}

/* ============================================================
   SEMANTIC TYPE CLASSES
   ============================================================ */

.tp-display {
  font-family: var(--tp-font);
  font-size: var(--tp-display-size);
  font-weight: var(--tp-display-weight);
  line-height: var(--tp-display-line);
  letter-spacing: var(--tp-display-track);
  color: var(--tp-fg-1);
}

.tp-h1 {
  font-family: var(--tp-font);
  font-size: var(--tp-h1-size);
  font-weight: var(--tp-h1-weight);
  line-height: var(--tp-h1-line);
  letter-spacing: var(--tp-h1-track);
  color: var(--tp-fg-1);
}

.tp-h2 {
  font-family: var(--tp-font);
  font-size: var(--tp-h2-size);
  font-weight: var(--tp-h2-weight);
  line-height: var(--tp-h2-line);
  letter-spacing: var(--tp-h2-track);
  color: var(--tp-fg-1);
}

.tp-h3 {
  font-family: var(--tp-font);
  font-size: var(--tp-h3-size);
  font-weight: var(--tp-h3-weight);
  line-height: var(--tp-h3-line);
  letter-spacing: var(--tp-h3-track);
  color: var(--tp-fg-1);
}

.tp-body-lg { font: var(--tp-w-regular) var(--tp-body-lg-size)/var(--tp-body-lg-line) var(--tp-font); color: var(--tp-fg-2); }
.tp-body    { font: var(--tp-w-regular) var(--tp-body-size)/var(--tp-body-line)       var(--tp-font); color: var(--tp-fg-2); }
.tp-body-sm { font: var(--tp-w-regular) var(--tp-body-sm-size)/var(--tp-body-sm-line) var(--tp-font); color: var(--tp-fg-3); }
.tp-caption { font: var(--tp-w-medium)  var(--tp-caption-size)/var(--tp-caption-line) var(--tp-font); color: var(--tp-fg-3); }

.tp-label {
  font-family: var(--tp-font);
  font-size: var(--tp-label-size);
  font-weight: var(--tp-label-weight);
  letter-spacing: var(--tp-label-track);
  text-transform: uppercase;
}

/* ============================================================
   BRAND DEVICES
   The layout grammar lifted from the brand deck. These are what make
   a page read as TonePerks rather than as a generic gradient site.
   ============================================================ */

/* --- Two-tone headline ---------------------------------------------
   The deck's strongest typographic device: a light-weight first word
   followed by a heavy coloured second word.
       <h2 class="tp-2tone">Brand <em>Colors</em></h2>
   ------------------------------------------------------------------ */
.tp-2tone       { font-weight: var(--tp-w-regular); }
.tp-2tone em    { font-style: normal; font-weight: var(--tp-w-black); color: var(--tp-purple); }
.tp-2tone.on-dark    { color: var(--tp-on-dark-1); }
.tp-2tone.on-dark em { color: var(--tp-pink); }

/* --- Gradient text — decorative emphasis only ---------------------- */
.tp-grad-text {
  background: var(--tp-grad-wave);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

/* --- Short thick rule under a display word ------------------------- */
.tp-rule::after {
  content: "";
  display: block;
  width: 64px;
  height: 4px;
  margin-top: var(--tp-s-4);
  background: var(--tp-grad-wave);
  border-radius: 2px;
}

/* --- Oversized deck numeral --------------------------------------- */
.tp-numeral {
  font-family: var(--tp-font);
  font-size: var(--tp-numeral-size);
  font-weight: var(--tp-numeral-weight);
  line-height: 0.85;
  letter-spacing: var(--tp-numeral-track);
  color: var(--tp-purple);
  font-variant-numeric: tabular-nums;
}

/* --- Eyebrow / section kicker ------------------------------------- */
.tp-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--tp-s-3);
  font-family: var(--tp-font);
  font-size: var(--tp-eyebrow-size);
  font-weight: var(--tp-w-bold);
  letter-spacing: var(--tp-eyebrow-track);
  text-transform: uppercase;
  color: var(--tp-purple);
}
.tp-eyebrow::before {
  content: "";
  width: 28px;
  height: 3px;
  border-radius: 2px;
  background: var(--tp-grad-wave);
  flex-shrink: 0;
}
.tp-eyebrow.on-dark { color: var(--tp-pink); }

/* --- Corner accent block (deck's bottom-left pink square) ---------- */
.tp-corner-block {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 56px;
  height: 96px;
  background: var(--tp-pink);
  pointer-events: none;
}

/* --- Vertical right-edge wordmark rule ----------------------------- */
.tp-edge-mark {
  position: absolute;
  top: 0;
  bottom: 0;
  right: 3.5vw;
  display: flex;
  align-items: center;
  gap: var(--tp-s-6);
  pointer-events: none;
  user-select: none;
}
.tp-edge-mark span {
  writing-mode: vertical-rl;
  font-family: var(--tp-font);
  font-size: var(--tp-label-size);
  font-weight: var(--tp-w-bold);
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--tp-purple);
  opacity: 0.5;
}
.tp-edge-mark::before {
  content: "";
  width: 1px;
  align-self: stretch;
  background: currentColor;
  opacity: 0.18;
}

/* ============================================================
   ACCESSIBLE PAIRING RULES — encoded, not just documented

   ALLOWED
     #1A0A1A / #453247 / #6B5870  on  white, #FDF6FB, #F7EAF3
     #8C006E (8.98:1) and #B40F69 (6.59:1)  on  white  — any size
     white (8.98:1)   on  #8C006E
     white (6.59:1)   on  #B40F69
     #1A0A1A (4.93:1) on  #F03278            <-- pink fields take DARK text
     white / rgba(255,255,255,>=0.66)  on  #1A0A1A

   FORBIDDEN
     white on #F03278            (3.87:1)  -- use --tp-grad-cta or dark text
     #F03278 as small body text  (3.87:1)  -- large/decorative only
     #F472B6 on white            (2.28:1)  -- dark grounds only
     #9C8BA1 as body text        (3.20:1)  -- placeholders / 18px+ only
   ============================================================ */

/* Pink field: force the dark foreground the ratio actually requires. */
.tp-field-pink {
  background: var(--tp-pink);
  color: var(--tp-dark);
}
.tp-field-pink .tp-eyebrow,
.tp-field-pink a { color: var(--tp-dark); }

/* Purple field: white is safe here. */
.tp-field-purple {
  background: var(--tp-purple);
  color: var(--tp-on-dark-1);
}

/* Dark field. */
.tp-field-dark {
  background: var(--tp-dark-1);
  color: var(--tp-on-dark-2);
}

/* ============================================================
   FOCUS — visible, brand-coloured, never removed.
   ============================================================ */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 3px solid var(--tp-focus);
  outline-offset: 3px;
  border-radius: var(--tp-r-xs);
}
/* On saturated pink grounds the pink ring would vanish — invert it. */
.tp-field-pink :where(a, button, input):focus-visible {
  outline-color: var(--tp-dark);
}
