/* Originally concatenated from the AVIDE Design System's tokens/*.css files in
   the fixed order (fonts, colors, typography, spacing, radius, elevation,
   motion, base), then deliberately hand-edited: the Google Fonts @import was
   removed (GDPR compliance, fonts are self-hosted instead), font src paths
   were rewritten to ../fonts/, and the display-face @font-face rules were
   moved out to inc/fonts.php. Do NOT regenerate this file by naive
   concatenation of the source tokens/*.css files, or the Google Fonts hotlink
   and the editor-facing display faces come back. */
/* ---- tokens/fonts.css ---- */
/* Montserrat is the ONLY packaged face with Vietnamese diacritics and the
   only family registered here as a usable, editor-facing font. Self-hosted:
   no Google Fonts hotlink, no @import. Weights 400/500/600/700/800 were all
   converted to woff2 and are self-hosted alongside this stylesheet.
   The four Latin-only display faces (Azonix, Big John PRO, Casanova Scotia,
   Fredoka One) are declared CSS-only in inc/fonts.php, not here, so no
   editor UI can ever surface them as a pickable/readable family. */
@font-face {
  font-family: "Montserrat";
  src: url("../fonts/Montserrat-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Montserrat";
  src: url("../fonts/Montserrat-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Montserrat";
  src: url("../fonts/Montserrat-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Montserrat";
  src: url("../fonts/Montserrat-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Montserrat";
  src: url("../fonts/Montserrat-800.woff2") format("woff2");
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}
/* ---- tokens/colors.css ---- */
:root {
  /* --- Brand primitives, sampled from assets/logos/avide-logo-full.svg --- */
  --avide-red: #EF3E23;        /* wordmark + primary action */
  --avide-red-tint: #EA988B;   /* the offset shadow inside the wordmark */
  --avide-amber: #FCB415;      /* secondary accent, never for body text */
  --avide-navy: #283350;       /* institutional voice, headings, dark surfaces */

  /* --- Brand ROLES. Read this before using a brand primitive directly. ---

     The logo is not red-dominant. In the mark, red and amber are highlights on a
     network that is mostly navy and blue, and the wordmark sits on a navy offset
     shadow. Weighting the interface the way the logo is weighted means navy leads.

     Three further reasons the primary is navy, not red:

     1. Red #EF3E23 measures 3.90:1 on white. It cannot carry text, links, thin
        icon strokes or small type without being swapped for --red-700 first. A
        value that needs a substitute every time it touches a letter is not doing
        a primary's job; it is doing an accent's job under the wrong name.
     2. AVIDE is non-profit, non-governmental: a professional and academic body.
        Saturated red is the highest-arousal hue in the palette: alert, sale,
        urgency. Exactly right on "Đăng ký hội viên"; wrong as the institutional
        voice of a charter, a board roster and a fee schedule.
     3. Large fields of red beside amber read as the Vietnamese flag. For a body
        that states in its own charter that it is non-governmental, that reading
        is a liability. Red kept small stays a brand colour; red made dominant
        starts to look like an emblem of state.

     Target weighting, by area: ~70% navy and neutral, ~20% white/surface,
     ~10% red and amber combined. Red appears at full strength on primary
     actions, the logo, and nowhere large. */
  --brand-primary:   var(--navy-700);   /* institutional field, headings, dark sections */
  --brand-accent:    var(--avide-red);  /* primary action, brand mark, small emphasis */
  --brand-highlight: var(--avide-amber);/* single warm highlight: eyebrow dots, gold tier */

  /* --- Red ramp (hue held at the logo red, chroma stepped in oklch) --- */
  --red-50:  oklch(0.968 0.017 32);
  --red-100: oklch(0.928 0.043 32);
  --red-200: oklch(0.869 0.081 32);
  --red-300: oklch(0.795 0.124 32);
  --red-400: oklch(0.717 0.166 32);
  --red-500: #EF3E23;
  --red-600: oklch(0.564 0.199 32);
  --red-700: oklch(0.475 0.167 32);
  --red-800: oklch(0.392 0.135 32);
  --red-900: oklch(0.315 0.104 32);

  /* --- Navy ramp --- */
  --navy-50:  oklch(0.972 0.008 265);
  --navy-100: oklch(0.937 0.017 265);
  --navy-200: oklch(0.874 0.031 265);
  --navy-300: oklch(0.784 0.048 265);
  --navy-400: oklch(0.643 0.066 265);
  --navy-500: oklch(0.512 0.073 265);
  --navy-600: oklch(0.421 0.070 265);
  --navy-700: #283350;
  --navy-800: oklch(0.276 0.050 265);
  --navy-900: oklch(0.213 0.040 265);

  /* --- Amber ramp --- */
  --amber-50:  oklch(0.983 0.019 85);
  --amber-100: oklch(0.955 0.052 85);
  --amber-200: oklch(0.915 0.098 85);
  --amber-300: oklch(0.877 0.140 85);
  --amber-400: oklch(0.838 0.163 85);
  --amber-500: #FCB415;
  --amber-600: oklch(0.706 0.153 75);
  --amber-700: oklch(0.590 0.130 68);

  /* --- Neutrals: one hue family with navy (265), very low chroma. Previously the
         light steps were warmed toward the red (hue 40) while the dark steps were
         already navy — the ramp changed temperature halfway down, which is why
         pale surfaces read faintly pink next to a navy card. --- */
  --neutral-0:   #FFFFFF;
  --neutral-25:  oklch(0.991 0.002 265);
  --neutral-50:  oklch(0.978 0.003 265);
  --neutral-100: oklch(0.958 0.005 265);
  --neutral-200: oklch(0.917 0.007 265);
  --neutral-300: oklch(0.856 0.009 265);
  --neutral-400: oklch(0.708 0.011 265);
  --neutral-500: oklch(0.578 0.012 265);
  --neutral-600: oklch(0.462 0.011 265);
  --neutral-700: oklch(0.372 0.014 265);
  --neutral-800: oklch(0.284 0.018 265);
  --neutral-900: oklch(0.208 0.020 265);

  /* --- Community palette: four categorical hues -------------------------------
     ADDITION, flagged. The logo contains exactly three inks — #EF3E23, #FCB415,
     #283350 (verified by sampling the artwork; there is no fourth hue hiding in
     the dot network). Three inks cannot label six Ban chuyên môn, five membership
     tiers and four activity types: everything collapses into red-or-amber and the
     page goes monotone, which is the flatness the design was suffering from.

     So two hues are DERIVED rather than invented — same oklch lightness and a
     chroma matched to the logo reds and ambers, only the hue angle rotated. They
     read as the same family at the same volume. Categorical use only: division
     tags, activity types, chart series, bloom backdrops. Never for chrome, never
     as a second brand colour. If AVIDE later publishes an official extended
     palette, replace these two lines and nothing else moves. */
  --accent-red:   oklch(0.564 0.199 32);   /* = --red-600, the logo ink */
  --accent-amber: oklch(0.706 0.153 75);   /* = --amber-600, the logo ink */
  --accent-teal:  oklch(0.600 0.115 178);  /* derived */
  --accent-blue:  oklch(0.580 0.140 245);  /* derived */

  --accent-red-soft:   oklch(0.962 0.022 32);
  --accent-amber-soft: oklch(0.964 0.032 75);
  --accent-teal-soft:  oklch(0.962 0.024 178);
  --accent-blue-soft:  oklch(0.960 0.026 245);

  /* --- Blooms: large, soft, very low-chroma washes placed behind content. -------
     The atmosphere layer. A flat white page under navy type reads institutional
     but inert; a wash at 4–8% chroma gives the section a temperature without
     tinting the type or touching contrast. Always behind, never under small text
     at more than 8% — measure if in doubt. */
  --bloom-warm:  radial-gradient(60% 70% at 20% 0%, oklch(0.93 0.075 40 / 0.62), transparent 70%);
  --bloom-gold:  radial-gradient(55% 65% at 85% 10%, oklch(0.94 0.085 80 / 0.60), transparent 70%);
  --bloom-cool:  radial-gradient(65% 75% at 90% 20%, oklch(0.93 0.055 245 / 0.60), transparent 72%);
  --bloom-teal:  radial-gradient(55% 70% at 10% 90%, oklch(0.93 0.050 178 / 0.55), transparent 70%);
  --bloom-navy:  radial-gradient(70% 80% at 15% 10%, oklch(0.42 0.090 265 / 0.55), transparent 72%);
  --bloom-ember: radial-gradient(60% 70% at 85% 85%, oklch(0.50 0.150 32 / 0.30), transparent 70%);

  /* Dark-surface blooms. A light wash laid over navy does not brighten it, it
     greys it — the pale gradient has nowhere to go but toward the midtone, and
     the band turns muddy. On dark, the wash has to be a LIGHT SOURCE: same hue,
     lower lightness, higher chroma, screened in. Never reuse the light blooms
     above on a navy surface. */
  --bloom-dark-warm: radial-gradient(62% 72% at 82% 88%, oklch(0.52 0.170 38 / 0.42), transparent 70%);
  --bloom-dark-gold: radial-gradient(58% 68% at 88% 82%, oklch(0.60 0.140 72 / 0.34), transparent 70%);
  --bloom-dark-cool: radial-gradient(66% 76% at 86% 16%, oklch(0.52 0.130 245 / 0.46), transparent 72%);
  --bloom-dark-teal: radial-gradient(58% 70% at 12% 88%, oklch(0.52 0.100 178 / 0.40), transparent 70%);

  /* --- Semantic status --- */
  --success-500: oklch(0.480 0.120 155);
  --success-50:  oklch(0.960 0.028 155);
  --warning-500: var(--amber-600);
  --warning-50:  var(--amber-50);
  --danger-500:  var(--red-600);
  --danger-50:   var(--red-50);
  --info-500:    oklch(0.560 0.100 240);
  --info-50:     oklch(0.960 0.020 240);

  /* --- Membership tiers (brochure p.3-4) --- */
  --tier-standard: var(--neutral-500);
  --tier-silver:   oklch(0.760 0.012 265);
  --tier-gold:     var(--amber-500);
  --tier-diamond:  oklch(0.700 0.085 225);
  --tier-sponsor:  var(--avide-red);

  /* --- Semantic surface + text aliases: use THESE in components --- */
  --surface-page:      var(--neutral-25);
  --surface-card:      var(--neutral-0);
  --surface-sunken:    var(--neutral-100);
  --surface-inverse:   var(--navy-700);
  --surface-primary:   var(--navy-700);   /* institutional fill — prefer this over --surface-brand for large areas */
  --surface-brand:     var(--red-600);
  --surface-brand-soft:var(--red-50);
  --surface-accent-soft: var(--amber-50);

  --text-heading:   var(--navy-700);
  --text-body:      var(--neutral-700);
  /* --neutral-500 measures 4.32:1 on white and 3.82:1 on --surface-sunken, so it
     fails AA at the 12–14px sizes secondary text actually uses. --neutral-600 is
     7.05 / 6.23. Keep --neutral-500 for non-text use (the --tier-standard dot). */
  --text-muted:     var(--neutral-600);
  --text-on-brand:  var(--neutral-0);
  --text-on-dark:   var(--neutral-0);
  --text-on-dark-muted: oklch(0.874 0.031 265);
  /* #EF3E23 measures 3.90:1 on white — a fill colour, not a text colour. Text and
     links take --red-700 (7.28:1 on white, 6.43:1 on sunken). Same rule as amber:
     the brand value tints surfaces and dots; a darker step carries the letters. */
  --text-brand:     var(--red-700);
  --text-link:      var(--red-700);
  --text-link-hover: var(--red-800);

  --border-subtle:  var(--neutral-200);
  --border-default: var(--neutral-300);
  --border-strong:  var(--navy-700);
  --border-brand:   var(--avide-red);
  /* Amber at 55% on white measured ~1.8:1 — a focus ring nobody can see. Navy on
     light surfaces, amber only where the surface is already navy. These two are
     the single source of truth; --ring-focus / --ring-focus-inverse in
     elevation.css are box-shadows BUILT FROM them, not parallel definitions. */
  --focus-ring:         var(--navy-600);
  --focus-ring-on-dark: var(--avide-amber);
}
/* ---- tokens/typography.css ---- */
:root {
  /* Families. --font-sans carries ALL Vietnamese copy. */
  --font-sans: "Montserrat", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-display: "Azonix", "Montserrat", sans-serif;      /* Latin only */
  --font-display-heavy: "Big John PRO", "Azonix", sans-serif; /* Latin only */
  --font-script: "Casanova Scotia", cursive;                /* Latin only */
  --font-rounded: "Fredoka One", "Montserrat", sans-serif;  /* Latin only */
  --font-mono: "SFMono-Regular", "Source Code Pro", Menlo, Consolas, monospace;

  /* Scale — 1.25 major third off a 16px base, rounded to whole px */
  --text-2xs: 11px;
  --text-xs:  12px;
  --text-sm:  14px;
  --text-base:16px;
  --text-md:  18px;
  --text-lg:  20px;
  --text-xl:  24px;
  --text-2xl: 30px;
  --text-3xl: 38px;
  --text-4xl: 48px;
  --text-5xl: 60px;
  --text-6xl: 76px;

  --leading-tight: 1.1;
  --leading-snug: 1.25;
  --leading-normal: 1.5;
  --leading-relaxed: 1.65;

  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;
  --weight-black: 800;

  /* Azonix and the wordmark are wide; Vietnamese headings are not. */
  --tracking-display: 0.06em;
  --tracking-eyebrow: 0.16em;
  --tracking-heading: -0.01em;
  --tracking-body: 0;

  /* Composed roles */
  --type-eyebrow: var(--weight-bold) var(--text-xs)/var(--leading-normal) var(--font-sans);
  --type-h1: var(--weight-black) var(--text-4xl)/var(--leading-tight) var(--font-sans);
  --type-h2: var(--weight-bold) var(--text-2xl)/var(--leading-snug) var(--font-sans);
  --type-h3: var(--weight-bold) var(--text-lg)/var(--leading-snug) var(--font-sans);
  --type-body: var(--weight-regular) var(--text-base)/var(--leading-relaxed) var(--font-sans);
  --type-body-lg: var(--weight-regular) var(--text-lg)/var(--leading-relaxed) var(--font-sans);
  --type-body-sm: var(--weight-regular) var(--text-sm)/var(--leading-normal) var(--font-sans);
  --type-label: var(--weight-semibold) var(--text-sm)/var(--leading-normal) var(--font-sans);
}
/* ---- tokens/spacing.css ---- */
:root {
  /* 4px base grid. AVIDE layouts are generous — default section rhythm is --space-16. */
  --space-0: 0px;
  --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;
  --space-32: 128px;

  --container-sm: 640px;
  --container-md: 840px;
  --container-lg: 1080px;
  --container-xl: 1240px;
  --gutter: var(--space-6);
  /* Section rhythm scales with the viewport instead of sitting at a flat 80px.
     A fixed 80px meant every pair of adjacent sections opened a 160px gap at
     every width, which reads as dead scroll on the section-heavy pages (Ban
     Chấp Hành stacks eight of them) and is far too much of a 375px screen.
     The ceiling is --space-16, the rhythm this file already documents above. */
  --section-y: clamp(var(--space-10), 4.5vw, var(--space-16));
}
/* ---- tokens/radius.css ---- */
:root {
  /* The wordmark is hard-cornered; the mark is all circles.
     The system keeps radii small on containers and fully round on pills/dots. */
  --radius-none: 0px;
  --radius-xs: 2px;
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-xl: 20px;
  --radius-full: 999px;
}
/* ---- tokens/elevation.css ---- */
:root {
  /* Shadows are navy-tinted, never neutral black. */
  --shadow-xs: 0 1px 2px oklch(0.28 0.05 265 / 0.06);
  --shadow-sm: 0 1px 3px oklch(0.28 0.05 265 / 0.08), 0 1px 2px oklch(0.28 0.05 265 / 0.04);
  --shadow-md: 0 4px 12px oklch(0.28 0.05 265 / 0.09), 0 1px 3px oklch(0.28 0.05 265 / 0.05);
  --shadow-lg: 0 12px 32px oklch(0.28 0.05 265 / 0.12), 0 2px 6px oklch(0.28 0.05 265 / 0.05);
  --shadow-brand: 0 6px 18px oklch(0.60 0.20 32 / 0.24);

  /* The wordmark's signature offset shadow, available for display type. */
  --shadow-offset-wordmark: 6px 6px 0 var(--avide-red-tint);

  /* Two rings, both DERIVED from --focus-ring / --focus-ring-on-dark in
     colors.css — change the colour there and the shadow follows. A single amber
     ring was invisible on white (1.8:1, below the 3:1 minimum for non-text
     indicators), so light surfaces get navy and only navy surfaces get amber. */
  --ring-focus: 0 0 0 3px var(--focus-ring);
  --ring-focus-inverse: 0 0 0 3px var(--focus-ring-on-dark);
}
/* ---- tokens/motion.css ---- */
:root {
  --duration-instant: 80ms;
  --duration-fast: 140ms;
  --duration-normal: 220ms;
  --duration-slow: 360ms;

  /* No bounce, no overshoot. AVIDE motion is quiet and institutional. */
  --ease-standard: cubic-bezier(0.2, 0, 0.2, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in: cubic-bezier(0.4, 0, 1, 1);

  --transition-control: background-color var(--duration-fast) var(--ease-standard),
                        border-color var(--duration-fast) var(--ease-standard),
                        color var(--duration-fast) var(--ease-standard),
                        box-shadow var(--duration-fast) var(--ease-standard),
                        transform var(--duration-fast) var(--ease-standard);
}
/* ---- tokens/base.css ---- */
/* Minimal resets + the two link rules every AVIDE surface inherits. */
*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  font: var(--type-body);
  color: var(--text-body);
  background: var(--surface-page);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  color: var(--text-heading);
  letter-spacing: var(--tracking-heading);
  text-wrap: pretty;
}

p { margin: 0; text-wrap: pretty; }

a {
  color: var(--text-link);
  text-decoration-color: color-mix(in oklch, var(--text-link) 35%, transparent);
  text-underline-offset: 0.18em;
  transition: color var(--duration-fast) var(--ease-standard);
}
a:hover { color: var(--text-link-hover); text-decoration-color: currentColor; }
a:focus-visible { outline: none; box-shadow: var(--ring-focus); border-radius: var(--radius-xs); }

:where(button, input, select, textarea) { font: inherit; }

/* The dot-network motif, as a reusable background. Derived from the logo mark. */
.avide-dotfield {
  background-image: radial-gradient(currentColor 1.5px, transparent 1.6px);
  background-size: 18px 18px;
  opacity: 0.16;
}
