/* tokens.css — canonical design tokens for ScholarshipHub.
   Loaded BEFORE any other stylesheet on every HTML page.
   See .claude/plans/unify-design-system.md for full spec.

   Phases:
   - P1 (this file ships): tokens defined, aliases bridge to old names.
     Existing CSS still wins via specificity / direct hex usage.
     Visual impact = ZERO until P2+ consumers land.
   - P2..P3 (later): selectors in landing.css / style.css / auth-pages.css /
     components consume var(--token) instead of raw hex.
   - P4 (cleanup): drop alias layer.

   Feature flag (§10 of plan):
   - Default: data-design="v2" → white premium palette (THIS).
   - Rollback: data-design="v1" → legacy values via override block at bottom.
   - Inline script in each HTML <head> sets data-design from meta tag.
*/

/* ── Canonical v2 tokens (white premium) ──────────────────────────────── */
:root {
  /* Surfaces */
  --bg-canvas:            #FFFFFF;          /* app shell: pure white */
  --bg-canvas-marketing:  #FAFAFA;          /* landing/pricing/blog/guides: subtle off-white */
  --bg-surface:           #FFFFFF;          /* cards, modals, inputs */
  --bg-elevated:          #FAFAFA;          /* sidebar, panels, hover sheets */
  --bg-sunken:            #F4F4F5;          /* inset wells, code, secondary panels */
  --bg-hover:             rgba(0,0,0,0.04);
  --bg-active:            rgba(37,110,91,0.08);
  --bg-overlay:           rgba(10,10,10,0.5);

  /* Text */
  --text-primary:    #0A0A0A;
  --text-secondary:  #3F3F46;
  --text-tertiary:   #71717A;
  --text-quaternary: #A1A1AA;
  --text-inverse:    #FFFFFF;

  /* Borders */
  --border:         #EAEAEA;
  --border-strong:  #D4D4D8;

  /* Accent — restrained teal on white */
  --accent:        #256E5B;
  --accent-hover:  #174A3E;
  --accent-soft:   #E5F1EC;

  /* Status */
  --danger:        #B54747;
  --danger-soft:   #F4E0DD;
  --success:       #2F855A;
  --success-soft:  #E2F1E8;
  --warning:       #B7791F;
  --warning-soft:  #F7EBD2;

  /* Radii */
  --radius-sm:    4px;
  --radius-md:    8px;
  --radius-lg:   16px;
  --radius-pill: 999px;

  /* Shadows */
  --shadow-sm:        0 1px 0 var(--border);
  --shadow-md:        0 8px 16px -10px rgba(10,10,10,0.06);
  --shadow-lg:        0 24px 48px -28px rgba(10,10,10,0.16);
  --shadow-inset-hi:  0 1px 0 rgba(255,255,255,0.65) inset;

  /* Typography */
  /* Display / editorial: DM Sans keeps headings elegant, compact, and fully
     aligned with the product UI. The stack stays system-safe for Vietnamese
     text and avoids loading a separate serif title face. */
  /*
    Display / editorial: DM Sans → "Segoe UI Variable" (Win 11) →
    "Segoe UI" (Win 10/8) → system-ui → Helvetica Neue → Arial → sans-serif.
  */
  --font-display: "DM Sans", "Segoe UI Variable", "Segoe UI", system-ui,
                  -apple-system, BlinkMacSystemFont, "Helvetica Neue",
                  Arial, sans-serif;

  /*
    Body / UI: DM Sans → "Segoe UI Variable" (Win 11) → "Segoe UI" (Win 10/8)
    → system-ui → -apple-system → Helvetica Neue → Arial → sans-serif.
    Order matters: Segoe UI before system-ui ensures Windows gets the right
    rendering instead of falling through to a generic alias.
  */
  --font-body: "DM Sans", "Segoe UI Variable", "Segoe UI", system-ui,
               -apple-system, BlinkMacSystemFont, "Helvetica Neue",
               Arial, sans-serif;

  /*
    Mono: standard cross-platform mono stack.
    "Cascadia Code" added for Windows 11 users — full Vietnamese support.
  */
  --font-mono: "Cascadia Code", ui-monospace, "SFMono-Regular", Menlo,
               Consolas, "Courier New", monospace;

  /* Motion */
  --motion-ease:        cubic-bezier(0.16, 1, 0.3, 1);     /* premium out */
  --motion-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1); /* gentle overshoot */
  --motion-ease-in:     cubic-bezier(0.7, 0, 0.84, 0);     /* exits */
  --motion-fast: 180ms;
  --motion-base: 260ms;
  --motion-slow: 420ms;
  --motion-page: 720ms;
}

/* ── Dark — pure mono charcoal (no warm tint) ──────────────────────────── */
:root[data-theme="dark"] {
  --bg-canvas:            #0A0A0A;
  --bg-canvas-marketing:  #0A0A0A;
  --bg-surface:           #171717;
  --bg-elevated:          #1F1F1F;
  --bg-sunken:            #0F0F0F;
  --bg-hover:             rgba(255,255,255,0.06);
  --bg-active:            rgba(94,178,154,0.16);
  --bg-overlay:           rgba(0,0,0,0.7);

  --text-primary:    #FAFAFA;
  --text-secondary:  #D4D4D8;
  --text-tertiary:   #A1A1AA;
  --text-quaternary: #71717A;
  --text-inverse:    #0A0A0A;

  --border:        #27272A;
  --border-strong: #3F3F46;

  --accent:        #5EB29A;
  --accent-hover:  #7DC9B2;
  --accent-soft:   rgba(94,178,154,0.16);

  --danger:        #E07474;
  --danger-soft:   rgba(224,116,116,0.16);
  --success:       #7BC295;
  --success-soft:  rgba(123,194,149,0.14);
  --warning:       #E0B062;
  --warning-soft:  rgba(224,176,98,0.14);

  --shadow-sm:       0 1px 0 var(--border);
  --shadow-md:       0 8px 16px -10px rgba(0,0,0,0.6);
  --shadow-lg:       0 24px 48px -28px rgba(0,0,0,0.8);
  --shadow-inset-hi: 0 1px 0 rgba(255,255,255,0.04) inset;
}

/* ── Back-compat alias layer (REMOVE in P4) ────────────────────────────────
   Lets existing CSS that consumes legacy names keep resolving while we
   migrate selectors over to canonical tokens. Order: alias points at canonical.
*/
:root,
:root[data-theme="dark"] {
  /* Old style.css names → canonical */
  --bg-primary:   var(--bg-surface);
  --bg-secondary: var(--bg-canvas);
  --bg-sidebar:   var(--bg-elevated);
  --bg-input:     var(--bg-surface);
  --bg-modal:     var(--bg-surface);

  /* Old status color names */
  --green:        var(--success);
  --green-light:  var(--success-soft);
  --red:          var(--danger);
  --red-light:    var(--danger-soft);
  --yellow:       var(--warning);
  --yellow-light: var(--warning-soft);

  /* Old accent helper */
  --accent-light: var(--accent-soft);

  /* Old landing.css names → canonical */
  --landing-bg:            var(--bg-canvas-marketing);
  --landing-panel:         var(--bg-elevated);
  --landing-panel-strong:  var(--bg-sunken);
  --landing-ink:           var(--text-primary);
  --landing-ink-soft:      var(--text-secondary);
  --landing-muted:         var(--text-tertiary);
  --landing-border:        var(--border-strong);
  --landing-border-soft:   var(--border);
  --landing-accent:        var(--accent);
  --landing-accent-hover:  var(--accent-hover);

  /* Old auth-pages.css helpers */
  --auth-serif: var(--font-display);
  --auth-sans:  var(--font-body);
  --auth-ease:  var(--motion-ease);
}

/* ── v1 rollback override (REMOVE 30 days post-deploy, §10.5) ──────────────
   When data-design="v1" is set on <html>, every token reverts to the
   pre-unification values. Lets ops flip palette without redeploy.
*/
:root[data-design="v1"] {
  /* Surfaces — warm cream (old landing) + black/white (old style.css mixed) */
  --bg-canvas:            #ffffff;
  --bg-canvas-marketing:  #FAFAF8;          /* old --landing-bg */
  --bg-surface:           #ffffff;
  --bg-elevated:          #F2F1EE;
  --bg-sunken:            #ECE9E2;
  --bg-hover:             rgba(0,0,0,0.05);
  --bg-active:            rgba(37,110,91,0.10);
  --bg-overlay:           rgba(0,0,0,0.5);

  /* Text — warm ink (old landing) */
  --text-primary:    #171717;
  --text-secondary:  #2E2C28;
  --text-tertiary:   #6B6761;
  --text-quaternary: #8A857D;

  /* Borders — old landing values */
  --border:        #E7E4DE;
  --border-strong: #D9D6CF;

  /* Accent unchanged (same teal) */
  --accent:       #256E5B;
  --accent-hover: #174A3E;
  --accent-soft:  rgba(37,110,91,0.14);
}

:root[data-design="v1"][data-theme="dark"] {
  /* Cool slate dark — old style.css */
  --bg-canvas:            #1c1c1e;
  --bg-canvas-marketing:  #1c1c1e;
  --bg-surface:           #2c2c2e;
  --bg-elevated:          #3a3a3c;
  --bg-sunken:            #1c1c1e;
  --bg-hover:             rgba(255,255,255,0.06);
  --bg-active:            rgba(94,178,154,0.18);
  --bg-overlay:           rgba(0,0,0,0.65);

  --text-primary:    #f5f5f7;
  --text-secondary:  #d1d1d6;
  --text-tertiary:   #98989d;
  --text-quaternary: #6e6e73;

  --border:        #38383a;
  --border-strong: #48484a;
}

/* ── Pre-render cloak — preserved from existing auth flow ──────────────── */
html[data-auth-cloak] body { visibility: hidden; }

/* ── Vietnamese diacritic safe zone — applies globally ─────────────────── */
:lang(vi) {
  line-height: 1.65;
  word-break: break-word;
}

:lang(vi) h1, :lang(vi) h2, :lang(vi) h3,
:lang(vi) h4, :lang(vi) h5, :lang(vi) h6 {
  line-height: 1.35;
}

:lang(vi) .card-cat,
:lang(vi) .eyebrow,
:lang(vi) .nav-links a,
:lang(vi) .post-card h3,
:lang(vi) .resource-card h3 {
  overflow: visible;
  line-height: 1.5;
}

/* ── Language switcher ─────────────────────────────────────────────────── */
/* Compact pill that lives in the nav rail alongside auth buttons / links.
 * Override §4.4's `min-height: 44px` because the switcher is a control
 * cluster, not a CTA — 44px would dwarf the surrounding nav. */
.lang-switcher {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--border-subtle, var(--border-strong));
  border-radius: var(--radius-pill);
  overflow: hidden;
  background: var(--bg-subtle, transparent);
  height: 28px;
  line-height: 1;
}
.lang-btn {
  min-height: 0;
  padding: 0 10px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--text-tertiary);
  transition: background var(--motion-fast) var(--motion-ease),
              color var(--motion-fast) var(--motion-ease);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.lang-btn:hover:not([aria-pressed="true"]) {
  color: var(--text-primary);
  background: var(--bg-hover, rgba(0, 0, 0, 0.04));
}
.lang-btn[aria-pressed="true"] {
  background: var(--accent);
  color: var(--text-inverse);
}

/* ── §4.4 — Button overflow safety for long Vietnamese strings ─────────── */
/* VN labels run 20–40% longer than EN equivalents. Without these rules a
 * CTA like "Tham gia làm Alumni & Mentor" clips diacritics or pushes the
 * button past its container at narrow widths. Wrap allowed, touch target
 * preserved, soft hyphenation for the worst-case strings. */
/* Explicit CTA list — opt-IN to the 44px touch target instead of
 * matching `button[class*="btn"]` (which captured filter chips, icon
 * buttons, doc actions, language switcher, track buttons, etc.). */
.landing-button,
.btn,
.btn-primary,
.btn-secondary,
.btn-text,
.btn-ghost,
.btn-danger,
.btn-full,
.btn-ai-process {
  white-space: normal;
  min-height: 44px;
  text-align: center;
  hyphens: auto;
  -webkit-hyphens: auto;
}

/* Single-line badges / chips — let them grow rather than clip diacritics. */
.mock-badge,
.card-cat,
.chip,
.eyebrow {
  white-space: nowrap;
  overflow: visible;
}

/* ── §4.5 — CLS hardening via font-size-adjust ─────────────────────────── */
/* Calibrated for DM Sans (x-height ratio ≈ 0.52). Keeps fallback metrics
 * close to the web font during display=optional swap, so the layout
 * doesn't reflow when DM Sans loads. Body inherits the variable stack. */
body {
  font-size-adjust: 0.52;
}

/* ── §5 — Plan + status semantic colors ─────────────────────────────────── */
/* Plan accent palette — used by pricing cards + badges. Each picks a Tailwind
 * 600/700 hue for the bold layer and the 100 hue for the soft tint. All AA
 * contrast on white verified.
 *
 * Applicant → neutral grey (free / starter signal)
 * Scribe    → brand green (the "Popular" middle tier)
 * Scholar   → blue (the "Recommended" power tier — differentiated from accent)
 */
:root {
  /* Applicant — neutral grey */
  --plan-applicant: #525252;          /* neutral-600 */
  --plan-applicant-hover: #404040;    /* neutral-700 */
  --plan-applicant-soft: #f5f5f5;     /* neutral-100 */
  --plan-applicant-border: rgba(82,82,82,.24);

  /* Scribe — brand green */
  --plan-scribe: var(--accent);
  --plan-scribe-hover: var(--accent-hover);
  --plan-scribe-soft: var(--accent-soft);
  --plan-scribe-border: rgba(37,110,91,.24);

  /* Scholar — blue */
  --plan-scholar: #2563eb;            /* blue-600 — AA 4.83:1 on white */
  --plan-scholar-hover: #1d4ed8;      /* blue-700 */
  --plan-scholar-soft: #dbeafe;       /* blue-100 */
  --plan-scholar-border: rgba(37,99,235,.24);

  /* Status colors — actions across forms, admin, modals.
   * cancel  → red (destructive)
   * save    → brand green (constructive write)
   * approve → green (positive moderation)
   */
  --status-cancel: #dc2626;           /* red-600 — AA 5.94:1 on white */
  --status-cancel-hover: #b91c1c;     /* red-700 */
  --status-cancel-soft: #fee2e2;      /* red-100 */
  --status-cancel-border: rgba(220,38,38,.32);

  --status-save: var(--accent);       /* brand green — AA on white */
  --status-save-hover: var(--accent-hover);
  --status-save-soft: var(--accent-soft);
  --status-save-border: rgba(37,110,91,.32);

  --status-approve: #15803d;          /* green-700 — AA 5.34:1 */
  --status-approve-hover: #166534;    /* green-800 */
  --status-approve-soft: #dcfce7;     /* green-100 */
  --status-approve-border: rgba(21,128,61,.32);
}

/* ── §5.1 — Status button classes ───────────────────────────────────────── */
/* Solid variants: high-contrast white text on color. Use for primary action
 * in a row (e.g. the Save button in a settings panel, Approve in moderation).
 * Soft variants (.btn-*-soft): tinted background + colored text. Use for
 * secondary or less-loud placements (e.g. a Cancel link in a quiet toolbar). */
.btn-cancel,
.btn-save,
.btn-approve,
.btn-cancel-soft,
.btn-save-soft,
.btn-approve-soft {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  /* Proper sizing — without these, the button collapses to text-only
   * dimensions and looks like the unstyled snippet in the screenshot.
   * Matches the height + padding rhythm of .btn-primary / .landing-button. */
  min-height: 38px;
  padding: 8px 18px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm, 8px);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0.005em;
  white-space: nowrap;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  transition: background var(--motion-fast, 160ms) var(--motion-ease, ease),
              border-color var(--motion-fast, 160ms) var(--motion-ease, ease),
              color var(--motion-fast, 160ms) var(--motion-ease, ease),
              transform var(--motion-fast, 160ms) var(--motion-ease, ease);
}
.btn-cancel:active,
.btn-save:active,
.btn-approve:active,
.btn-cancel-soft:active,
.btn-save-soft:active,
.btn-approve-soft:active { transform: translateY(1px); }
.btn-cancel:disabled,
.btn-save:disabled,
.btn-approve:disabled,
.btn-cancel-soft:disabled,
.btn-save-soft:disabled,
.btn-approve-soft:disabled { opacity: 0.6; cursor: not-allowed; transform: none; }
/* Small variant aligned with existing .btn-small. */
.btn-cancel.btn-small,
.btn-save.btn-small,
.btn-approve.btn-small,
.btn-cancel-soft.btn-small,
.btn-save-soft.btn-small,
.btn-approve-soft.btn-small {
  min-height: 30px;
  padding: 5px 12px;
  font-size: 13px;
}

.btn-cancel  { background: var(--status-cancel);  color: #fff; border-color: var(--status-cancel); }
.btn-save    { background: var(--status-save);    color: #fff; border-color: var(--status-save); }
.btn-approve { background: var(--status-approve); color: #fff; border-color: var(--status-approve); }

.btn-cancel:hover  { background: var(--status-cancel-hover);  border-color: var(--status-cancel-hover); }
.btn-save:hover    { background: var(--status-save-hover);    border-color: var(--status-save-hover); }
.btn-approve:hover { background: var(--status-approve-hover); border-color: var(--status-approve-hover); }

.btn-cancel-soft  { background: var(--status-cancel-soft);  color: var(--status-cancel);  border: 1px solid var(--status-cancel-border); }
.btn-save-soft    { background: var(--status-save-soft);    color: var(--status-save);    border: 1px solid var(--status-save-border); }
.btn-approve-soft { background: var(--status-approve-soft); color: var(--status-approve); border: 1px solid var(--status-approve-border); }

.btn-cancel-soft:hover  { background: #fecaca; }
.btn-save-soft:hover    { background: #bbf7d0; }
.btn-approve-soft:hover { background: #bbf7d0; }

/* Alias so existing .btn-danger usages pick up the new red without churn. */
.btn-danger { background: var(--status-cancel); color: #fff; border-color: var(--status-cancel); }
.btn-danger:hover { background: var(--status-cancel-hover); border-color: var(--status-cancel-hover); }

/* Keyboard-focus rings — WCAG AA. :focus-visible only so mouse clicks stay
 * clean. Outline color tracks the button's own status hue. */
.btn-cancel:focus-visible       { outline: 2px solid var(--status-cancel);  outline-offset: 2px; }
.btn-save:focus-visible         { outline: 2px solid var(--status-save);    outline-offset: 2px; }
.btn-approve:focus-visible      { outline: 2px solid var(--status-approve); outline-offset: 2px; }
.btn-cancel-soft:focus-visible  { outline: 2px solid var(--status-cancel);  outline-offset: 2px; }
.btn-save-soft:focus-visible    { outline: 2px solid var(--status-save);    outline-offset: 2px; }
.btn-approve-soft:focus-visible { outline: 2px solid var(--status-approve); outline-offset: 2px; }
.btn-danger:focus-visible       { outline: 2px solid var(--status-cancel);  outline-offset: 2px; }

/* Dark-mode soft-tint overrides — the light 100-hue tints (#FEE2E2 etc.)
 * glare on dark surfaces. Swap to translucent dark tints + brighter text so
 * contrast holds. Solid variants need no adjustment (already use #fff text). */
html[data-theme="dark"] {
  --status-cancel-soft:  rgba(220, 38, 38, 0.18);
  --status-save-soft:    rgba(34, 197, 94, 0.18);
  --status-approve-soft: rgba(34, 197, 94, 0.18);

  --plan-applicant-soft: rgba(163, 163, 163, 0.10);
  --plan-scholar-soft:   rgba(59, 130, 246, 0.18);
}
html[data-theme="dark"] .btn-cancel-soft  { color: #fca5a5; }
html[data-theme="dark"] .btn-save-soft    { color: #86efac; }
html[data-theme="dark"] .btn-approve-soft { color: #86efac; }
