/* ==========================================================================
   Nubuilt - design tokens
   The single source of truth. Nothing below this file invents a value.
   ========================================================================== */

:root {
  /* ---- Colour ---------------------------------------------------------- */
  --graphite:        #1C1C1C;   /* headings, nav, premium backgrounds, footer */
  --stone:           #C8B79C;   /* highlights, dividers, accent sections      */
  --blue:            #0066FF;   /* buttons, fills, digital elements           */
  --blue-text:       #0060F5;   /* the same blue as TEXT: see the note below   */
  --paper:           #F5F3EF;   /* page background, cards                     */
  --grey:            #6B6B6B;   /* body text, secondary information           */

  /* Electric Blue as text on Architectural White measures 4.36:1, just under
     the 4.5:1 WCAG AA needs for body text. As a fill it is fine: white on
     Electric Blue is 5.94:1, so buttons keep the exact brand colour. Only the
     text form is darkened, by an amount that is not visible side by side and
     takes it to 4.75:1. tests/audit-test.py computes both from these values,
     so changing either one back is caught rather than argued about. */

  /* Derived - tinted rather than opacity-shifted, so text stays crisp. */
  --graphite-900:    #111111;
  --graphite-700:    #333333;
  --paper-pure:      #FFFFFF;
  --paper-shade:     #EBE8E2;
  --stone-light:     #E3DACB;
  --stone-dark:      #A8926F;
  --grey-light:      #9A9A9A;
  --hairline:        rgba(28, 28, 28, 0.12);
  --hairline-invert: rgba(245, 243, 239, 0.18);

  /* Semantic states. Muted deliberately: a form error on this palette should
     read as information, not as an emergency. */
  --alert:           #A32A21;
  --alert-tint:      #F7E9E7;
  --ok:              #2F6B4F;
  --ok-tint:         #E7F0EB;
  --warn:            #8A5A00;
  --warn-tint:       #F7EEDC;

  /* ---- Type ------------------------------------------------------------ */
  --font-display: "General Sans", "Inter", -apple-system, BlinkMacSystemFont,
                  "Segoe UI", system-ui, sans-serif;
  --font-body:    "Inter", -apple-system, BlinkMacSystemFont,
                  "Segoe UI", system-ui, sans-serif;
  --font-mono:    ui-monospace, "SF Mono", "Cascadia Mono", Menlo, monospace;

  /* Fluid scale. Clamped so nothing collapses on a 320px phone or balloons
     on a 27" monitor. Ratio 1.25 mobile, widening to 1.333 at desktop. */
  --step--2: clamp(0.69rem, 0.67rem + 0.11vw, 0.75rem);
  --step--1: clamp(0.83rem, 0.79rem + 0.19vw, 0.94rem);
  --step-0:  clamp(1.00rem, 0.95rem + 0.26vw, 1.13rem);
  --step-1:  clamp(1.20rem, 1.11rem + 0.44vw, 1.50rem);
  --step-2:  clamp(1.44rem, 1.29rem + 0.73vw, 2.00rem);
  --step-3:  clamp(1.73rem, 1.49rem + 1.17vw, 2.66rem);
  --step-4:  clamp(2.07rem, 1.71rem + 1.82vw, 3.55rem);
  --step-5:  clamp(2.49rem, 1.94rem + 2.75vw, 4.73rem);
  --step-6:  clamp(2.99rem, 2.17rem + 4.08vw, 6.31rem);
  --step-7:  clamp(3.58rem, 2.38rem + 6.00vw, 8.41rem);

  --lh-tight:   0.98;
  --lh-heading: 1.06;
  --lh-snug:    1.35;
  --lh-body:    1.62;

  --tracking-display: -0.035em;  /* large type needs negative tracking */
  --tracking-heading: -0.02em;
  --tracking-body:     0em;
  --tracking-eyebrow:  0.14em;   /* small caps labels need air */

  --weight-regular: 400;
  --weight-medium:  500;
  --weight-semi:    600;

  /* ---- Space ----------------------------------------------------------- */
  --space-3xs: 0.25rem;
  --space-2xs: 0.5rem;
  --space-xs:  0.75rem;
  --space-s:   1rem;
  --space-m:   1.5rem;
  --space-l:   2.5rem;
  --space-xl:  4rem;
  --space-2xl: 6rem;
  --space-3xl: clamp(5rem, 10vw, 10rem);   /* between major sections */

  /* ---- Layout ---------------------------------------------------------- */
  --measure:     68ch;                       /* readable line length */
  --gutter:      clamp(1.25rem, 5vw, 4rem);
  --container:   96rem;
  --container-narrow: 68rem;
  --grid-columns: 12;
  --header-h:    5.5rem;
  --header-h-condensed: 4.25rem;

  /* ---- Form ------------------------------------------------------------ */
  --radius:      4px;    /* "rounded but not playful" */
  --radius-lg:   8px;
  --border:      1px;

  /* ---- Motion ---------------------------------------------------------- */
  --ease-out-arch: cubic-bezier(0.16, 1, 0.30, 1);  /* the house curve */
  --ease-in-out:   cubic-bezier(0.65, 0, 0.35, 1);
  --ease-soft:     cubic-bezier(0.33, 1, 0.68, 1);

  --dur-fast: 180ms;
  --dur-base: 320ms;
  --dur-slow: 560ms;
  --dur-hero: 900ms;
  --stagger:   70ms;

  /* ---- Depth ----------------------------------------------------------- */
  --shadow-card:  0 1px 2px rgba(28, 28, 28, 0.04), 0 8px 24px rgba(28, 28, 28, 0.06);
  --shadow-lift:  0 2px 4px rgba(28, 28, 28, 0.05), 0 16px 48px rgba(28, 28, 28, 0.10);

  --z-header:   100;
  --z-menu:     200;
  --z-lightbox: 300;
  --z-toast:    400;
}

/* Dark surfaces invert the palette rather than recolouring each element. */
.is-dark {
  --paper:      var(--graphite);
  --paper-pure: var(--graphite-900);
  --paper-shade:var(--graphite-700);
  --graphite:   #F5F3EF;
  --grey:       #A5A19A;
  /* On graphite the darkened text blue drops to 3.4:1, so dark surfaces get a
     lighter one. Same reasoning, opposite direction. */
  --blue-text:  #5C9BFF;
  --hairline:   var(--hairline-invert);
  color: var(--graphite);
  background: var(--paper);
}
