/*
 * Domainsansar design tokens.
 *
 * One source of truth for colour, elevation, radius and typography. Components
 * reference semantic roles (`surface`, `border-subtle`, `text-muted`) rather
 * than raw palette steps, so the two themes stay in step and a palette change
 * is a change in one file.
 *
 * Three rules the product brief makes non-negotiable, encoded here:
 *
 *   1. NO GRADIENTS. There is no gradient token, in any form. Depth comes from
 *      layered opaque surfaces, hairline borders and restrained shadow.
 *   2. Light mode is TRUE WHITE as the page canvas, not off-white. Separation
 *      between layers comes from borders and shadow, not from tinting the page.
 *   3. Glass is a highlight, not a texture. One blur strength exists, and it is
 *      reserved for surfaces that float over content -- the sticky header and
 *      modal scrims.
 */

@custom-variant dark (&:where([data-theme='dark'], [data-theme='dark'] *));

/* ------------------------------------------------------------------------- */
/* Palette                                                                    */
/* ------------------------------------------------------------------------- */

:root {
  /*
   * Brand accent: a deep marine teal. Chosen to read as considered and
   * financial rather than energetic -- the platform is asking people to move
   * five-figure sums, and a bright saturated brand colour undercuts that. It is
   * also deliberately distinct from the indigo and violet that dominate
   * developer-tool branding.
   */
  --accent-50: #f1f8fa;
  --accent-100: #dcedf1;
  --accent-200: #b9dbe4;
  --accent-300: #8ac2d1;
  --accent-400: #52a1b7;
  --accent-500: #31839c;
  --accent-600: #226c85;
  --accent-700: #1e586d;
  --accent-800: #1f495a;
  --accent-900: #1d3d4b;
  --accent-950: #102733;

  /* Neutrals. Very slightly cool so white surfaces read crisp, not creamy. */
  --neutral-0: #ffffff;
  --neutral-25: #fcfcfd;
  --neutral-50: #f7f8f9;
  --neutral-100: #eff1f3;
  --neutral-200: #e3e6ea;
  --neutral-300: #cbd1d8;
  --neutral-400: #9aa3af;
  /* 450 exists solely as the form-control border: the lightest value that
     still clears the 3:1 WCAG requires for a control boundary on white. */
  --neutral-450: #858f9d;
  /* Darkened from #6f7885, which measured 4.47:1 on white and 4.20:1 on the
     sunken fill -- both short of the 4.5:1 AA floor for body text. */
  --neutral-500: #68707d;
  --neutral-600: #545c68;
  --neutral-700: #3f4651;
  --neutral-800: #2a3038;
  --neutral-900: #1a1e24;
  --neutral-950: #12151a;
  --neutral-1000: #0c0e12;

  /* Semantic hues. Used for state, never for decoration. */
  --positive-100: #dcf5e5;
  --positive-500: #22a05c;
  --positive-600: #15803d;
  --positive-700: #106431;

  --caution-100: #fdeecd;
  --caution-500: #d08700;
  --caution-600: #a96a00;
  --caution-700: #85540b;

  --critical-100: #fde3e3;
  --critical-500: #dc4444;
  --critical-600: #bf2626;
  --critical-700: #9c1f1f;

  /* Premium marker. A restrained brass, not a gold gradient. */
  --premium-100: #f7edd6;
  --premium-500: #b08422;
  --premium-600: #8f6a17;
}

/* ------------------------------------------------------------------------- */
/* Light theme (default)                                                      */
/* ------------------------------------------------------------------------- */

:root {
  /* True white page. Depth is built on top of it, not tinted into it. */
  --canvas: var(--neutral-0);

  /* Cards and panels: also white, separated by border and shadow. */
  --surface: var(--neutral-0);
  --surface-raised: var(--neutral-0);

  /* The one tinted fill, for inset areas: table headers, code, inputs at rest. */
  --surface-sunken: var(--neutral-50);
  --surface-hover: var(--neutral-50);
  --surface-active: var(--neutral-100);

  /*
   * Glass: for surfaces that float over scrolling content.
   *
   * This opacity is a contrast floor, not a taste call, and it is the reason the
   * effect is not pushed further. Whatever scrolls underneath becomes part of
   * the background the navigation text sits on, so the figure has to hold up
   * against the worst of it -- a near-black band, which is what a dark card or
   * an image gives you.
   *
   * At 0.72, white over #12151a composites to roughly #a5a6a8: secondary
   * navigation text still clears 4.5:1. Dropping to 0.62 looks marginally more
   * transparent and takes that same text to about 2.4:1, which fails. The glass
   * read comes from the edge highlight, the blur and the saturation lift below
   * rather than from more transparency.
   */
  --surface-glass: rgb(255 255 255 / 0.72);

  /*
   * The lit top edge of a pane of glass. This is what makes the effect read as
   * glass rather than as low opacity: real glass catches light on the edge
   * facing the viewer, and without it a translucent bar just looks faded.
   */
  --glass-edge: rgb(255 255 255 / 0.9);

  --surface-scrim: rgb(18 21 26 / 0.4);

  /*
   * Three border roles, not one, and the distinction is an accessibility
   * requirement rather than a stylistic nicety.
   *
   * `subtle` is decoration -- card edges, dividers, table rules. It carries no
   * information a user must perceive to operate the interface, so it is free to
   * stay a true hairline.
   *
   * `control` is the resting edge of an input, checkbox or select. WCAG 1.4.11
   * requires 3:1 against the adjacent surface for anything that identifies a
   * control's boundary, and the old hairline measured 1.25:1 -- so a
   * low-vision user could not see where a field began. It is the lightest
   * value that clears the requirement, which keeps the crispness the design
   * asks for without failing the people the rule exists for.
   */
  --border-subtle: var(--neutral-200);
  --border-control: var(--neutral-450);
  --border-strong: var(--neutral-300);
  --border-accent: var(--accent-600);

  --text-primary: var(--neutral-900);
  --text-secondary: var(--neutral-600);
  --text-muted: var(--neutral-500);
  --text-inverted: var(--neutral-0);
  --text-accent: var(--accent-700);

  --accent-solid: var(--accent-600);
  --accent-solid-hover: var(--accent-700);
  --accent-solid-active: var(--accent-800);
  --accent-soft: var(--accent-50);
  --accent-soft-border: var(--accent-200);

  --positive-solid: var(--positive-600);
  --positive-soft: var(--positive-100);
  --positive-text: var(--positive-700);

  --caution-solid: var(--caution-600);
  --caution-soft: var(--caution-100);
  --caution-text: var(--caution-700);

  --critical-solid: var(--critical-600);
  --critical-soft: var(--critical-100);
  --critical-text: var(--critical-700);

  --premium-soft: var(--premium-100);
  --premium-text: var(--premium-600);

  /*
   * Shadows are deliberately shallow. A marketplace built of deep drop shadows
   * looks like a consumer app; the trust signal here is precision.
   */
  --shadow-xs: 0 1px 2px 0 rgb(18 21 26 / 0.04);
  --shadow-sm: 0 1px 3px 0 rgb(18 21 26 / 0.06), 0 1px 2px -1px rgb(18 21 26 / 0.04);
  --shadow-md: 0 4px 12px -2px rgb(18 21 26 / 0.08), 0 2px 4px -2px rgb(18 21 26 / 0.04);
  --shadow-lg: 0 12px 32px -8px rgb(18 21 26 / 0.12), 0 4px 8px -4px rgb(18 21 26 / 0.06);

  /*
   * A bare colour rather than a full shadow, because the glass surface composes
   * its own: the drop shadow has to sit in the same box-shadow declaration as
   * the inset edge highlight, and a second declaration would replace the first.
   */
  --shadow-color-glass: rgb(18 21 26 / 0.18);

  /* Focus ring, stated once so every interactive element matches. */
  --ring: var(--accent-500);

  color-scheme: light;
}

/* ------------------------------------------------------------------------- */
/* Dark theme                                                                 */
/* ------------------------------------------------------------------------- */

[data-theme='dark'] {
  --canvas: var(--neutral-1000);

  /* Surfaces lift by getting lighter, which is how depth reads in the dark. */
  --surface: var(--neutral-950);
  --surface-raised: var(--neutral-900);
  --surface-sunken: var(--neutral-1000);
  --surface-hover: #171b21;
  --surface-active: #1d222a;

  /*
   * Held at the same opacity as light mode, for the mirrored reason: here the
   * worst case behind the bar is a light region, which lifts the dark surface
   * towards mid-grey and pushes the light navigation text the other way.
   */
  --surface-glass: rgb(12 14 18 / 0.72);

  /*
   * Far weaker than its light-mode counterpart, and deliberately so. A bright
   * edge on a dark surface is read as a light source; at the light-mode value
   * it stops looking like an edge and starts looking like a stray divider.
   */
  --glass-edge: rgb(255 255 255 / 0.08);

  --surface-scrim: rgb(4 5 7 / 0.64);

  --border-subtle: #242a33;
  /* 3.18:1 against the elevated surface -- the dark-mode counterpart of the
     light control border, for the same reason. */
  --border-control: #5b6777;
  --border-strong: #333b46;
  --border-accent: var(--accent-500);

  --text-primary: #e7eaee;
  --text-secondary: #a8b1bd;
  --text-muted: #7d8794;
  --text-inverted: var(--neutral-1000);
  --text-accent: var(--accent-300);

  /*
   * The accent lifts in the dark, but not as far as the raw 500.
   *
   * White text on #31839c measured 4.32:1 -- under the 4.5:1 AA floor, which
   * mattered because the primary button is filled with this and its label is
   * 14px. This value gives white 4.80:1 while still reading 4.02:1 against the
   * canvas, so the button remains obviously a button.
   */
  --accent-solid: #2e7b93;
  --accent-solid-hover: var(--accent-400);
  --accent-solid-active: var(--accent-300);
  --accent-soft: rgb(49 131 156 / 0.14);
  --accent-soft-border: rgb(49 131 156 / 0.3);

  --positive-solid: var(--positive-500);
  --positive-soft: rgb(34 160 92 / 0.14);
  --positive-text: #6ee7a3;

  --caution-solid: var(--caution-500);
  --caution-soft: rgb(208 135 0 / 0.14);
  --caution-text: #f0c164;

  --critical-solid: var(--critical-500);
  --critical-soft: rgb(220 68 68 / 0.14);
  --critical-text: #f79a9a;

  --premium-soft: rgb(176 132 34 / 0.16);
  --premium-text: #ddb95f;

  /* Shadow does little on a dark canvas; borders carry the separation. */
  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.3);
  --shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.4);
  --shadow-md: 0 4px 12px -2px rgb(0 0 0 / 0.5);
  --shadow-lg: 0 16px 40px -12px rgb(0 0 0 / 0.6);

  /* Heavier than light mode: on a dark page a faint shadow is invisible. */
  --shadow-color-glass: rgb(0 0 0 / 0.5);

  --ring: var(--accent-400);

  color-scheme: dark;
}

/* ------------------------------------------------------------------------- */
/* Tailwind theme bridge                                                      */
/* ------------------------------------------------------------------------- */

/*
 * `inline` keeps the generated utilities pointing at the custom properties
 * rather than resolving them at build time, which is what lets the theme swap
 * at runtime without a second stylesheet.
 */
@theme inline {
  --color-canvas: var(--canvas);
  --color-surface: var(--surface);
  --color-surface-raised: var(--surface-raised);
  --color-surface-sunken: var(--surface-sunken);
  --color-surface-hover: var(--surface-hover);
  --color-surface-active: var(--surface-active);
  --color-surface-glass: var(--surface-glass);
  --color-surface-scrim: var(--surface-scrim);

  --color-border-subtle: var(--border-subtle);
  --color-border-control: var(--border-control);
  --color-border-strong: var(--border-strong);
  --color-border-accent: var(--border-accent);

  --color-text-primary: var(--text-primary);
  --color-text-secondary: var(--text-secondary);
  --color-text-muted: var(--text-muted);
  --color-text-inverted: var(--text-inverted);
  --color-text-accent: var(--text-accent);

  --color-accent: var(--accent-solid);
  --color-accent-hover: var(--accent-solid-hover);
  --color-accent-active: var(--accent-solid-active);
  --color-accent-soft: var(--accent-soft);
  --color-accent-soft-border: var(--accent-soft-border);

  --color-positive: var(--positive-solid);
  --color-positive-soft: var(--positive-soft);
  --color-positive-text: var(--positive-text);

  --color-caution: var(--caution-solid);
  --color-caution-soft: var(--caution-soft);
  --color-caution-text: var(--caution-text);

  --color-critical: var(--critical-solid);
  --color-critical-soft: var(--critical-soft);
  --color-critical-text: var(--critical-text);

  --color-premium-soft: var(--premium-soft);
  --color-premium-text: var(--premium-text);

  --color-ring: var(--ring);

  /* Typography. Inter for the interface, with a real system fallback stack. */
  --font-sans:
    'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto,
    'Helvetica Neue', Arial, sans-serif;
  --font-mono:
    'JetBrains Mono', ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas,
    monospace;

  /* Radii. Soft, not pill-shaped. */
  --radius-xs: 0.25rem;
  --radius-sm: 0.375rem;
  --radius-md: 0.5rem;
  --radius-lg: 0.75rem;
  --radius-xl: 1rem;
  --radius-2xl: 1.25rem;

  --shadow-xs: var(--shadow-xs);
  --shadow-sm: var(--shadow-sm);
  --shadow-md: var(--shadow-md);
  --shadow-lg: var(--shadow-lg);

  /*
   * One blur strength, so glass is consistent wherever it appears.
   *
   * Sized to defocus text passing underneath into texture rather than leaving
   * it legible-but-smeared, which is what reads as a rendering fault.
   */
  --blur-glass: 20px;

  /*
   * Breakpoints matching the widths the product brief names, rather than
   * Tailwind's defaults.
   *
   * Two additions matter. `xs` at 430px separates the large-phone band
   * (430/414/390) from the small one (375/360), which the default 640px `sm`
   * step could not distinguish -- so a layout tuned for a Pro Max was being
   * applied unchanged to an SE. And `2xl` moves from 1536 to 1440, the width
   * the brief actually calls out, so wide-desktop rules fire where they were
   * designed to.
   */
  --breakpoint-xs: 26.875rem;
  --breakpoint-sm: 40rem;
  --breakpoint-md: 48rem;
  --breakpoint-lg: 64rem;
  --breakpoint-xl: 80rem;
  --breakpoint-2xl: 90rem;
}
