/* ==========================================================================
   Grem design tokens.

   This is the first file. Nothing else on the site writes a literal color,
   spacing, radius, or duration; stylesheets read these tokens instead.

   The values are the same ones in app/lib/design/tokens.dart, so the site
   and the app are one interface rather than two that resemble each other.
   Where a value differs, the comment says why.

   Two tiers. Primitives are raw and are referenced only from the semantic
   block below them. Components touch semantic tokens only. If a color
   cannot be named by its role it is decoration, and it does not belong here.

   Every contrast figure below is measured, not estimated.
   ========================================================================== */

:root {
  /* ---------------------------------------------------------------------
     PRIMITIVES
     --------------------------------------------------------------------- */

  --gray-0:   #ffffff;
  --gray-50:  #f8f9fa;
  --gray-100: #f1f3f5;
  --gray-200: #e9ecef;
  --gray-300: #dee2e6;
  --gray-400: #ced4da;
  --gray-500: #adb5bd;
  --gray-600: #868e96;
  --gray-650: #666d75;
  --gray-700: #495057;
  --gray-900: #212529;
  --gray-950: #121212; /* Never #000 as a surface. */

  /* One muted teal, carried over from the app. Terminal heritage without
     tipping into neon. Light and dark get genuinely different steps, because
     a hue that passes on white commonly fails on near-black. */
  --teal-100: #cce9e3;
  --teal-200: #99d3c8;
  --teal-400: #4dbfae;
  --teal-600: #0d7368;
  --teal-700: #0a5a51;
  --teal-dark-subtle: #12302c;

  /* Control boundaries. Two steps darker than the app's, because the web
     stacks controls on a sunken surface the app does not have, and #868e96
     measures 2.99:1 there. These clear 3:1 on every surface in the set. */
  --gray-outline:      #80878f;
  --gray-outline-dark: #70707a;

  --red-100: #fee2e2;
  --red-400: #f87171;
  --red-600: #dc2626;
  --red-700: #b91c1c;
  --red-dark-subtle: #3f1d1d;

  --amber-100: #fef3c7;
  --amber-400: #fbbf24;
  --amber-700: #b45309;
  --amber-dark-subtle: #3d2f0f;

  --green-100: #dcfce7;
  --green-400: #4ade80;
  --green-700: #15803d;
  --green-dark-subtle: #143024;

  --dark-raised:  #1c1c1e;
  --dark-overlay: #252528;
  --dark-sunken:  #0d0d0d;
  --dark-text:    #e5e7eb; /* Not pure white, which blooms on dark. */
  --dark-border:  #2e2e32;

  /* Spacing. One 8-point scale, with 4 for fine alignment. 8-based because
     it lands on whole pixels at 1.5x, 2x, and 3x. Nothing off this scale. */
  --space-1:  4px;
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  24px;
  --space-6:  32px;
  --space-7:  40px;
  --space-8:  48px;
  --space-9:  64px;
  --space-10: 80px;
  --space-11: 96px;

  /* Radius. Nested shapes stay concentric: inner = outer minus the padding
     between them. Full round is for status dots only. */
  --radius-xs:   4px;
  --radius-sm:   8px;
  --radius-md:   12px;
  --radius-lg:   16px;
  --radius-full: 9999px;

  /* Type. Every line height is a multiple of 4, and tightens as size grows. */
  --text-xs:   12px;  --leading-xs:   16px;
  --text-sm:   14px;  --leading-sm:   20px;
  --text-base: 16px;  --leading-base: 24px;
  --text-md:   18px;  --leading-md:   28px;
  --text-lg:   20px;  --leading-lg:   28px;
  --text-xl:   24px;  --leading-xl:   32px;
  --text-2xl:  32px;  --leading-2xl:  40px;
  --text-3xl:  40px;  --leading-3xl:  48px;

  --weight-regular:  400;
  --weight-medium:   500;
  --weight-semibold: 600;
  --weight-bold:     700;
  /* Light weights are banned. They fail at small sizes and in dark mode. */

  /* Motion. Nothing exceeds 400ms. */
  --duration-instant: 100ms;
  --duration-fast:    150ms;
  --duration-normal:  200ms;
  --duration-slow:    300ms;

  --ease-standard:   cubic-bezier(0.2, 0, 0, 1);
  --ease-decelerate: cubic-bezier(0, 0, 0, 1);
  --ease-accelerate: cubic-bezier(0.3, 0, 1, 1);
  /* These three are the whole set. A curve that overshoots its end value
     reads as a toy and slows down anything done repeatedly. */

  /* Shadow. Two layers, no x-offset, tinted with the background hue rather
     than black, which would gray out the surface underneath. Higher
     elevation is larger and fainter, never darker. There is no level 4:
     past this, use a tonal surface step. */
  --shadow-color: 210 12% 35%;
  --shadow-1:
    0 1px 2px 0 hsl(var(--shadow-color) / 0.10),
    0 1px 3px 1px hsl(var(--shadow-color) / 0.06);
  --shadow-2:
    0 1px 2px 0 hsl(var(--shadow-color) / 0.09),
    0 2px 6px 2px hsl(var(--shadow-color) / 0.05);
  --shadow-3:
    0 1px 3px 0 hsl(var(--shadow-color) / 0.08),
    0 4px 8px 3px hsl(var(--shadow-color) / 0.04);

  --border-width: 1px;
  --focus-ring-width: 2px;
  --focus-ring-offset: 2px;

  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui,
               "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", "Cascadia Mono",
               Menlo, Consolas, monospace;

  /* ---------------------------------------------------------------------
     SEMANTIC TOKENS. Components use only these.
     --------------------------------------------------------------------- */

  /* Surfaces. Depth comes from these steps, not from shadow. */
  --color-surface-page:    var(--gray-50);
  --color-surface-raised:  var(--gray-0);
  --color-surface-overlay: var(--gray-0);
  --color-surface-sunken:  var(--gray-100);

  /* Text. Four steps covers everything. Ratios are against the page
     surface, which is the worst case of the three light surfaces. */
  --color-text-primary:   var(--gray-900); /* 14.6:1 */
  --color-text-secondary: var(--gray-700); /*  7.8:1 */
  --color-text-tertiary:  var(--gray-650); /*  5.0:1. The floor for any text
                                               a person has to read. */
  --color-text-disabled:  var(--gray-500); /*  2.0:1. Exempt under WCAG
                                               1.4.3, and the only token
                                               allowed below 4.5:1. */
  --color-text-on-accent: var(--gray-0);   /*  5.7:1 on --color-action */

  /* Borders. The distinction is load-bearing. --color-border divides; it
     does not identify a control, so it is exempt from 1.4.11.
     --color-border-strong is the boundary of an interactive control and
     clears 3:1 on every surface here. Never put --color-border on an input
     or a button, and never use either as a text color. */
  --color-border:        var(--gray-300);     /* 1.3:1, decorative only */
  --color-border-strong: var(--gray-outline); /* 3.5:1 page, 3.3:1 sunken */

  /* Action. Interactive elements only, never decorative. The moment this
     appears on something static it stops meaning "action". */
  --color-action:        var(--teal-600); /* 5.4:1 on the page surface */
  --color-action-hover:  var(--teal-700); /* 8.1:1 */
  --color-action-subtle: var(--teal-100);
  --color-on-subtle:     var(--teal-700); /* 6.3:1 on --color-action-subtle */
  --color-focus-ring:    var(--teal-600);

  /* Status. Each is used as text, so each clears 4.5:1 on the page surface.
     The -subtle token is only ever the fill behind the -on-subtle text. */
  --color-danger:            var(--red-600);   /* 4.6:1 */
  --color-danger-subtle:     var(--red-100);
  --color-danger-on-subtle:  var(--red-700);   /* 5.3:1 */
  --color-warning:           var(--amber-700); /* 4.8:1 */
  --color-warning-subtle:    var(--amber-100);
  --color-warning-on-subtle: var(--amber-700); /* 4.5:1 */
  --color-success:           var(--green-700); /* 4.8:1 */
  --color-success-subtle:    var(--green-100);
  --color-success-on-subtle: var(--green-700); /* 4.6:1 */

  /* State layers. Overlays of the element's own content color, so a hover
     is never a second hand-picked hex that drifts from its rest color. */
  --state-hover-opacity:   8%;
  --state-pressed-opacity: 12%;
  --state-disabled-container: 12%;
  --state-disabled-content:   38%;

  /* Composite spacing. Named for where they are used, not for their size. */
  --space-inset-card:    var(--space-5);
  --space-inset-card-sm: var(--space-4);
  --space-gutter:        var(--space-4);
  --space-gutter-lg:     var(--space-6);
  --space-section:       var(--space-8);
  --space-stack-tight:   var(--space-2);
  --space-stack:         var(--space-4);
  --space-stack-loose:   var(--space-5);

  --size-target-min: 44px; /* Touch. 24px is the absolute WCAG floor. */
  --size-control-sm: 32px;
  --size-control-md: 40px;
  --size-control-lg: 48px;

  --measure:     68ch;  /* 45 to 75 characters of running prose. */
  --width-page:  1120px;
  --width-text:  720px;
  --width-form:  448px;
}

/* ==========================================================================
   DARK MODE

   Not an inversion. The accent gets its own lighter step, because
   --teal-600 measures 1.6:1 on near-black and would be unreadable. Surfaces
   are near-black rather than black, to limit halation.
   ========================================================================== */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-surface-page:    var(--gray-950);
    --color-surface-raised:  var(--dark-raised);
    --color-surface-overlay: var(--dark-overlay);
    --color-surface-sunken:  var(--dark-sunken);

    --color-text-primary:   var(--dark-text); /* 15.1:1 on the page */
    --color-text-secondary: var(--gray-400);  /* 12.5:1 */
    --color-text-tertiary:  var(--gray-500);  /*  9.0:1 */
    --color-text-disabled:  var(--gray-600);  /*  5.6:1 */
    --color-text-on-accent: var(--gray-950);  /*  8.4:1 on --color-action */

    --color-border:        var(--dark-border);        /* 1.3:1 */
    --color-border-strong: var(--gray-outline-dark);  /* 3.8:1 page */

    --color-action:        var(--teal-400); /* 8.4:1 on the page surface */
    --color-action-hover:  var(--teal-200);
    --color-action-subtle: var(--teal-dark-subtle);
    --color-on-subtle:     var(--teal-400); /* 6.3:1 on the subtle fill */
    --color-focus-ring:    var(--teal-400);

    --color-danger:            var(--red-400);   /* 6.2:1 */
    --color-danger-subtle:     var(--red-dark-subtle);
    --color-danger-on-subtle:  var(--red-400);   /* 5.4:1 */
    --color-warning:           var(--amber-400); /* 10.2:1 */
    --color-warning-subtle:    var(--amber-dark-subtle);
    --color-warning-on-subtle: var(--amber-400); /* 7.8:1 */
    --color-success:           var(--green-400); /* 9.8:1 */
    --color-success-subtle:    var(--green-dark-subtle);
    --color-success-on-subtle: var(--green-400); /* 8.2:1 */

    --shadow-color: 0 0% 0%;
  }
}

/* The same set again, for an explicit choice that overrides the system. */
:root[data-theme="dark"] {
  --color-surface-page:    var(--gray-950);
  --color-surface-raised:  var(--dark-raised);
  --color-surface-overlay: var(--dark-overlay);
  --color-surface-sunken:  var(--dark-sunken);
  --color-text-primary:   var(--dark-text);
  --color-text-secondary: var(--gray-400);
  --color-text-tertiary:  var(--gray-500);
  --color-text-disabled:  var(--gray-600);
  --color-text-on-accent: var(--gray-950);
  --color-border:        var(--dark-border);
  --color-border-strong: var(--gray-outline-dark);
  --color-action:        var(--teal-400);
  --color-action-hover:  var(--teal-200);
  --color-action-subtle: var(--teal-dark-subtle);
  --color-on-subtle:     var(--teal-400);
  --color-focus-ring:    var(--teal-400);
  --color-danger:            var(--red-400);
  --color-danger-subtle:     var(--red-dark-subtle);
  --color-danger-on-subtle:  var(--red-400);
  --color-warning:           var(--amber-400);
  --color-warning-subtle:    var(--amber-dark-subtle);
  --color-warning-on-subtle: var(--amber-400);
  --color-success:           var(--green-400);
  --color-success-subtle:    var(--green-dark-subtle);
  --color-success-on-subtle: var(--green-400);
  --shadow-color: 0 0% 0%;
}
