/**
 * SingleNotAlone design tokens.
 *
 * Mirrors design/tokens.json and theme.json. All three must agree.
 * Loaded on the front end and in the block editor, so the editor preview
 * matches what visitors see.
 *
 * Fonts are Geist and IBM Plex Mono (both SIL OFL), self hosted as woff2 only.
 * There are no requests to Google Fonts or any other external host. See
 * sna_disable_remote_fonts() in functions.php for the four layers that keep it
 * that way.
 */

/* ---------------------------------------------------------------------------
 * 1. Fonts
 *
 * ONE family: Geist, in four weights, for display, body, navigation and UI.
 * IBM Plex Mono is retained for the small uppercase labels only.
 *
 * Why one family. The owner asked for the register MKBHD uses. That look is a
 * single clean neo-grotesque worked hard across weights, not a display face
 * paired with a text face, so pairing two here would have missed the brief
 * however good the pair was.
 *
 * Why Geist and not the real thing. See docs: the fonts actually associated
 * with that brand are commercial (FF DIN, Aeonik) and cannot be self hosted
 * without a purchased licence. Geist is SIL OFL, sits in the same modern
 * neo-grotesque register, and can legally be served from this site, which
 * keeps the zero external request guarantee intact.
 * ------------------------------------------------------------------------ */

@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/geist-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/geist-latin-500-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/geist-latin-600-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/geist-latin-700-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/geist-latin-ext-400-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/geist-latin-ext-500-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/geist-latin-ext-600-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/geist-latin-ext-700-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono-latin-500-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono-latin-ext-500-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Geist";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/geist-latin-400-italic.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/geist-latin-ext-400-italic.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------------------------------------------------------------------------
 * 2. Metric matched fallbacks
 *
 * Measured for Geist against Arial. Note the two ratios: text weights need
 * 103.2% and the 600 display weight needs 108.02%, because the heavier cut is
 * genuinely wider. The text value is used, since body copy is what a mismatch
 * would visibly reflow.
 * ------------------------------------------------------------------------ */

@font-face {
  font-family: "Geist Fallback";
  src: local("Arial"), local("Helvetica"), local("Liberation Sans");
  size-adjust: 103.2%;
  ascent-override: 97.38%;
  descent-override: 28.59%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "IBM Plex Mono Fallback";
  src: local("Courier New"), local("Courier"), local("Liberation Mono");
  size-adjust: 99.98%;
  ascent-override: 102.52%;
  descent-override: 27.5%;
  line-gap-override: 0%;
}

/* ---------------------------------------------------------------------------
 * 3. Tokens
 * ------------------------------------------------------------------------ */

:root {
  /* Colour. Usage restrictions are enforced in theme.json and components.css,
     not just described here. See design/contrast-report.md. */
  --brand-plum:       #1B0B2A; /* near black purple, dark sections */
  --brand-purple:     #5B2A86; /* primary */
  --brand-purple-700: #452066; /* hover, pressed */
  --brand-purple-100: #EDE4F5; /* tints, cards, badges */
  --brand-gold:       #C9A227; /* accent */
  --brand-gold-200:   #E8CE7A; /* gold on dark, soft rules */
  --brand-black:      #0A0A0A;
  --brand-ivory:      #FBF9F6; /* page background */
  --brand-ink:        #241E2B; /* body text */
  --brand-muted:      #6E6875; /* secondary text */

  /* Derived. brand-muted darkened 3%, used only on purple-100, where the
     undarkened value measures 4.36:1 and misses AA. Applied automatically
     by the scoping rule in section 5, never chosen by an author. */
  --brand-muted-tint: #6B6571;

  /* Contextual aliases. Components reference these rather than raw tokens,
     which is what lets a dark section restyle its contents by swapping four
     values instead of overriding every rule. */
  --surface:          var(--brand-ivory);
  --text:             var(--brand-ink);
  --text-secondary:   var(--brand-muted);
  --accent:           var(--brand-purple);
  --rule:             rgba(27, 11, 42, 0.12);

  /* Form validation.
     The one place on this site where a colour has to carry a meaning, so it is
     chosen to clear 4.5:1 as body text on BOTH light grounds it can appear on:
     7.75:1 on ivory, 6.60:1 on the purple tint. The palette has no red, and it
     should not gain one for anything decorative. Errors only. */
  --error: #9B1C1C;

  /* Type */
  --font-heading: "Geist", "Geist Fallback", -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
  --font-body:    "Geist", "Geist Fallback", -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
  --font-mono:    "IBM Plex Mono", "IBM Plex Mono Fallback", ui-monospace, "Courier New", monospace;

  --step--1: clamp(0.875rem, 0.84rem + 0.18vw, 0.95rem);
  --step-0:  clamp(1rem,    0.96rem + 0.22vw, 1.125rem);
  --step-1:  clamp(1.25rem, 1.16rem + 0.45vw, 1.5rem);
  --step-2:  clamp(1.55rem, 1.38rem + 0.85vw, 2.1rem);
  --step-3:  clamp(1.95rem, 1.62rem + 1.6vw,  3rem);
  --step-4:  clamp(2.4rem,  1.85rem + 2.7vw,  4rem);

  --lh-body:    1.65;
  --lh-heading: 1.15;
  --measure: 46ch;
  /* 46ch, not 65ch. The ch unit is the advance width of the "0" glyph, which
     in Geist is 11.94px while the average character in running text is 8.72px,
     a ratio of 1.37. So a 65ch cap renders as 89 characters per line, not 65,
     and every capped paragraph on the page measured 75 to 84. Measured, not
     estimated: 46ch lands at about 63 characters, inside the 45 to 70 target. */
  --tracking-label: 0.08em;

  /* Space */
  --space-3xs: 0.25rem;
  --space-2xs: 0.5rem;
  --space-xs:  0.75rem;
  --space-s:   1rem;
  --space-m:   1.5rem;
  --space-l:   2rem;
  --space-xl:  3rem;
  --space-2xl: 4rem;
  --space-3xl: 6rem;
  --space-section: clamp(3.5rem, 2.5rem + 5vw, 7rem);

  /* Layout */
  --width-content: 42rem;
  --width-wide:    72rem;
  --gutter:        clamp(1.25rem, 0.9rem + 1.6vw, 2.5rem);

  /* Surface treatment. One radius, one shadow. */
  --radius:       8px;
  --radius-badge: 999px;
  --shadow: 0 1px 2px rgba(27, 11, 42, 0.04), 0 8px 24px rgba(27, 11, 42, 0.06);
  --hairline: 1px;

  /* Motion */
  --motion-travel:   8px;
  --motion-duration: 240ms;
  --motion-easing:   cubic-bezier(0.22, 0.61, 0.36, 1);
}


/* ---------------------------------------------------------------------------
 * 3b. REDESIGN TOKEN SYSTEM
 *
 * Named per the redesign brief. Where a brief name maps onto an existing brand
 * value the existing value is kept rather than nudged: every one of them is
 * already measured in design/contrast-report.md, and changing a hex by two
 * percent invalidates that report for a difference no one can see.
 *
 * Two tokens are genuinely new, and both were measured before being added:
 *
 *   --gold-text   Gold as text on light. Plain --gold is 2.30:1 on cream and
 *                 fails AA outright, which the brief correctly flagged. This is
 *                 gold darkened 36%: 5.09:1 on cream, 4.72:1 on the lavender
 *                 wash. Use it for any gold WORD. --gold stays for rules,
 *                 icons, borders and fills, where 1.4.11 does not apply.
 *
 *   --gold-deep   The dark stop of the foil gradient. 4.81:1 on cream, so a
 *                 foil edge still reads on a light ground.
 * ------------------------------------------------------------------------ */

:root {
  /* Surfaces */
  --ink-deep:     var(--brand-plum);
  --purple-royal: var(--brand-purple);
  --purple-wash:  #F4EFF8;
  --cream:        var(--brand-ivory);

  /* Gold, in three roles that must not be confused */
  --gold:         var(--brand-gold);
  --gold-bright:  #F0DA95;
  --gold-deep:    #8A6A16;
  --gold-text:    #816819;

  /* Derived text */
  --text-primary: var(--brand-ink);
  --text-muted:   var(--brand-muted);

  /* Modular type scale, 1.25 ratio. Nothing in component CSS should set a
     font-size in rem or px directly; use one of these. */
  --t-xs:   0.8rem;
  --t-sm:   0.9rem;
  --t-base: clamp(1.06rem, 1.02rem + 0.18vw, 1.125rem);
  --t-md:   1.25rem;
  --t-lg:   clamp(1.35rem, 1.25rem + 0.45vw, 1.55rem);
  --t-xl:   clamp(1.7rem, 1.5rem + 0.9vw, 2rem);
  --t-2xl:  clamp(2rem, 1.7rem + 1.4vw, 3rem);
  --t-3xl:  clamp(2.2rem, 1.7rem + 2.4vw, 4rem);

  /* Measure and rhythm, per the brief.
     --measure is deliberately NOT redeclared here. It has one definition,
     above, and this block used to carry a second at 65ch that silently
     overrode it, which is why every capped paragraph on the page measured 75
     to 89 characters while the token appeared to say 46. */
  --lh-body:   1.7;
  --lh-display: 1.12;
  --track-display: -0.022em;
  --track-label:   0.14em;
}

/* ---------------------------------------------------------------------------
 * 4. Kadence bridge
 *
 * Kadence renders its entire chrome (header, footer, hero band, buttons,
 * links, container widths) from its own --global-* custom properties, which
 * ship as a blue and grey default palette. Overriding the resulting selectors
 * one at a time would be endless and would break on every parent update.
 *
 * Remapping the variables instead means the parent theme draws itself in our
 * palette, from one place, using only public custom properties. No parent file
 * is touched, so Kadence remains updatable.
 *
 * The mapping follows Kadence's own semantics for each slot, so a component we
 * have not styled yet still comes out on brand rather than blue.
 * ------------------------------------------------------------------------ */

:root {
  /* Accent and interactive */
  --global-palette1: var(--brand-purple);
  --global-palette2: var(--brand-purple-700);
  --global-palette-highlight: var(--brand-purple);
  --global-palette-highlight-alt: var(--brand-purple-700);
  --global-palette-highlight-alt2: var(--brand-ivory);

  /* Text, darkest to lightest */
  --global-palette3: var(--brand-plum);  /* headings */
  --global-palette4: var(--brand-ink);   /* body */
  --global-palette5: var(--brand-muted); /* secondary */
  --global-palette6: var(--brand-muted); /* meta, borders */

  /* Surfaces. palette7 is the hero band, which shipped as #EDF2F7 and was the
     one visible non brand colour on the page. Ivory keeps the page reading as
     a single calm surface; the purple tint stays reserved for cards. */
  --global-palette7: var(--brand-ivory);
  --global-palette8: var(--brand-ivory);
  --global-palette9: var(--brand-ivory);
  --global-palette9rgb: 251, 249, 246;

  /* Buttons. Kadence draws these before our component CSS applies, so they
     need to be right at the variable level too. */
  --global-palette-btn: var(--brand-ivory);
  --global-palette-btn-bg: var(--brand-purple);
  --global-palette-btn-hover: var(--brand-ivory);
  --global-palette-btn-bg-hover: var(--brand-purple-700);
  --global-palette-btn-sec: var(--brand-purple-700);
  --global-palette-btn-sec-bg: var(--brand-purple-100);
  --global-palette-btn-sec-hover: var(--brand-ivory);
  --global-palette-btn-sec-bg-hover: var(--brand-purple);

  /* Container widths, mapped to our layout tokens. The calc variable is
     defined separately by Kadence from literal pixels, so overriding the
     source width alone would leave it stale. */
  --global-content-width: var(--width-wide);
  --global-content-narrow-width: var(--width-content);
  --global-calc-content-width: calc(var(--width-wide) - var(--gutter) - var(--gutter));
}

/* ---------------------------------------------------------------------------
 * 5. Dark surfaces
 *
 * Swapping the contextual aliases is what makes gold text legal here and
 * nowhere else. Gold on plum measures 7.7:1, gold-200 on plum 12.01:1.
 * ------------------------------------------------------------------------ */

.is-surface-plum,
.is-style-sna-surface-plum,
.has-brand-plum-background-color,
.is-surface-black,
.has-brand-black-background-color {
  --surface:        var(--brand-plum);
  --text:           var(--brand-ivory);
  --text-secondary: var(--brand-gold-200);
  --accent:         var(--brand-gold);
  --rule:           rgba(232, 206, 122, 0.32);

  color: var(--text);
}

.is-surface-black,
.has-brand-black-background-color {
  --surface: var(--brand-black);
}

/* ---------------------------------------------------------------------------
 * 6. Tint surfaces
 *
 * The only place brand-muted is substituted. An author writing secondary text
 * inside a tint card gets the accessible value automatically.
 * ------------------------------------------------------------------------ */

.is-surface-tint,
.is-style-sna-surface-tint,
.has-brand-purple-100-background-color {
  --surface:        var(--brand-purple-100);
  --text:           var(--brand-ink);
  --text-secondary: var(--brand-muted-tint);
  --accent:         var(--brand-purple-700);
  --rule:           rgba(69, 32, 102, 0.20);
}

/* ---------------------------------------------------------------------------
 * 7. Reduced motion
 *
 * Global kill switch. Any animation added later inherits this, so it cannot
 * be forgotten in a component.
 * ------------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
