@import "tailwindcss";
@import "tw-animate-css";

@layer base {
  :root {
    --background: 0 0% 100%;
    --foreground: 222.2 84% 4.9%;
    --card: 0 0% 100%;
    --card-foreground: 222.2 84% 4.9%;
    --popover: 0 0% 100%;
    --popover-foreground: 222.2 84% 4.9%;
    --primary: 221.2 83.2% 53.3%;
    --primary-foreground: 210 40% 98%;
    /* Neutrals sit at ~16% saturation rather than the stock 40%, so the chrome
       reads as grey next to the map instead of tinting blue. --accent is one
       step darker than --muted so hover fills register on white surfaces. */
    --secondary: 220 16% 96%;
    --secondary-foreground: 222.2 47.4% 11.2%;
    --muted: 220 16% 96%;
    /* Darkened from 46.9% L so secondary text meets WCAG AA (4.5:1) even on the
       muted/secondary backgrounds it is paired with (e.g. kbd badges). */
    --muted-foreground: 215.4 16.3% 40%;
    --accent: 220 16% 94%;
    --accent-foreground: 222.2 47.4% 11.2%;
    --destructive: 0 84.2% 60.2%;
    --destructive-foreground: 210 40% 98%;
    /* --border is decorative (dividers, panel edges); --input is a control
       boundary, so it is deliberately darker. See the note in .dark below. */
    --border: 220 15% 88%;
    --input: 220 13% 76%;
    --ring: 221.2 83.2% 53.3%;
    /* 0.375rem rather than shadcn's stock 0.5rem: a dense tool UI reads sharper,
       and the derived md/sm steps (calc -2px/-4px) stay positive. */
    --radius: 0.375rem;

    /* Elevation shadow colours, consumed by the --shadow-* scale the app defines
       in index.css. Two layers: penumbra is the wide soft spread, umbra the
       tight contact shadow.

       These are plain custom properties precisely so they inherit. Tailwind v4
       registers its own --tw-shadow-color with `inherits: false`, so retinting
       shadows by setting that on :root silently does nothing — the value has to
       reach each element, which ordinary inheritance does and @property-
       registered custom properties do not.

       Light shadows are a cool near-navy rather than pure black; against the
       neutral chrome it reads less muddy than #000 at the same alpha. */
    --elev-penumbra: hsl(220 40% 12% / 0.06);
    --elev-umbra: hsl(220 40% 12% / 0.1);
  }

  /* Dark mode is built as an explicit elevation ladder. Previously --background,
     --card and --popover were all 222.2 84% 4.9%, and --border, --input,
     --muted, --secondary and --accent were all 217.2 32.6% 17.5% — five tokens,
     one colour — so panels, dialogs and menus were indistinguishable from the
     app canvas and only a 1px border separated them. Each step below is a
     distinct surface:

       background  9%   app canvas / base chrome
       card       12%   toolbar, docked panels
       popover    15%   menus, tooltips, dialogs
       muted      20%   inset fills (status bar, wells)
       accent     22%   hover fill — must read above popover, since menu items
                        sit on it

     Saturation also drops from 84% to ~22%: the old value was a strongly
     blue-tinted near-black that clashed with satellite imagery in the map view.
     Every foreground/surface pair here clears WCAG AA 4.5:1 (lowest is
     muted-foreground on accent at 4.82:1). */
  .dark {
    --background: 222 24% 9%;
    --foreground: 210 40% 98%;
    --card: 222 22% 12%;
    --card-foreground: 210 40% 98%;
    --popover: 222 21% 15%;
    --popover-foreground: 210 40% 98%;
    --primary: 217.2 91.2% 59.8%;
    --primary-foreground: 222.2 47.4% 11.2%;
    --secondary: 220 18% 20%;
    --secondary-foreground: 210 40% 98%;
    --muted: 220 18% 20%;
    --muted-foreground: 215 20.2% 65.1%;
    --accent: 220 18% 22%;
    --accent-foreground: 210 40% 98%;
    --destructive: 0 62.8% 30.6%;
    --destructive-foreground: 210 40% 98%;
    --border: 220 14% 26%;
    --input: 220 12% 38%;
    /* Tailwind's built-in shadow scale bakes in a 10%-black colour, which is
       all but invisible against these surfaces — so before this, every one of
       the app's ~65 shadow utilities did nothing in dark mode and elevation was
       carried entirely by the surface ladder above. Pure black at a much higher
       alpha is what actually reads on a dark UI. */
    --elev-penumbra: hsl(0 0% 0% / 0.4);
    --elev-umbra: hsl(0 0% 0% / 0.55);

    /* Matches --primary, so the focus ring stays visible against the lifted
       surfaces (4.98:1 on --background, 4.64:1 on --card). The violet, rose and
       amber schemes below already pair ring with primary this way; emerald was
       the one exception and is brought into line there, since the lifted
       surfaces left its darker ring almost no headroom. */
    --ring: 217.2 91.2% 59.8%;
  }

  /* Accent color schemes. Each scheme overrides only the accent-bearing tokens
     (primary / its foreground / focus ring); the neutral base inherited from
     :root and .dark is left untouched. Selected via a `data-theme` attribute on
     <html> (see apps/.../lib/theme-schemes.ts). The default "blue" scheme needs
     no block here because it equals the base :root / .dark values above. */
  [data-theme="violet"] {
    --primary: 262.1 83.3% 57.8%;
    --primary-foreground: 210 20% 98%;
    --ring: 262.1 83.3% 57.8%;
  }
  [data-theme="violet"].dark {
    --primary: 263.4 70% 50.4%;
    --primary-foreground: 210 20% 98%;
    --ring: 263.4 70% 50.4%;
  }

  [data-theme="emerald"] {
    --primary: 142.1 76.2% 36.3%;
    --primary-foreground: 355.7 100% 97.3%;
    --ring: 142.1 76.2% 36.3%;
  }
  /* Unlike violet/rose/amber, emerald's dark ring used to sit well below its
     primary (142.4 71.8% 29.2%). Against the old near-black canvas that still
     cleared the 3:1 focus-indicator floor at 3.98:1, but the lifted surfaces in
     .dark drop it to 3.65:1 on --background and 3.13:1 on --popover — passing
     by ~4%, so any later surface tweak would break it. Pairing ring with
     primary restores the headroom (8.04:1 on --background) and makes the
     ring == primary invariant hold across every scheme. */
  [data-theme="emerald"].dark {
    --primary: 142.1 70.6% 45.3%;
    --primary-foreground: 144.9 80.4% 10%;
    --ring: 142.1 70.6% 45.3%;
  }

  [data-theme="rose"] {
    --primary: 346.8 77.2% 49.8%;
    --primary-foreground: 355.7 100% 97.3%;
    --ring: 346.8 77.2% 49.8%;
  }
  /* Rose intentionally shares one mid-lightness accent across light and dark
     (matching the upstream shadcn rose palette); 49.8% L reads on both, so
     unlike the other schemes the dark block is deliberately not adjusted. */
  [data-theme="rose"].dark {
    --primary: 346.8 77.2% 49.8%;
    --primary-foreground: 355.7 100% 97.3%;
    --ring: 346.8 77.2% 49.8%;
  }

  /* Amber's primary is a mid-brightness orange, so foreground text uses a dark
     brown (not near-white) to meet contrast on the primary surface in both
     modes — consistent with the contrast-maximizing pick in foregroundForHex. */
  [data-theme="amber"] {
    --primary: 24.6 95% 53.1%;
    --primary-foreground: 26 83.3% 14.1%;
    --ring: 24.6 95% 53.1%;
  }
  [data-theme="amber"].dark {
    --primary: 20.5 90.2% 48.2%;
    --primary-foreground: 26 83.3% 14.1%;
    --ring: 20.5 90.2% 48.2%;
  }

  * {
    @apply border-border;
  }

  body {
    @apply bg-background text-foreground;
  }

  /* Keyboard focus fallback: a visible, theme-aware focus ring for any
     interactive element that doesn't already manage its own. Components that
     render their own ring (Button, Input, dialog close, etc.) set
     `focus-visible:outline-none`, whose utility layer wins over this base rule,
     so they keep their existing indicator and don't double up.
     Note: the dialog close button uses the older `focus:outline-none` form,
     which also silences this outline correctly. Any future component using
     `focus:ring-*` WITHOUT `focus-visible:outline-none` would get both this
     outline and its own ring, so prefer the `focus-visible:` variants. */
  :focus-visible {
    outline: 2px solid hsl(var(--ring));
    outline-offset: 2px;
  }
}
